the_menace
2008-11-14T12:22:22Z
It says in the wiki instruction on site integration that you can use your own role and member provider but the profile provider needs to be inherited from YAF. Does this mean that I can't use my own custom provider? I have several custom fields such as address, city, sex, etc. How do I modify my provider section in order to integrate and use that with the YAF?

I want to be able to have people sign up on my site's own registration and automatically have them sign up on the forums as well. Please let me know how this works. I have everything installed correctly, just the integration part is a little bit rocky at this point. Thanks everyone.
Sponsor
Jaben
  •  Jaben
  • 100% (Exalted)
  • YAF Developer
2008-11-19T02:16:10Z
You can use any provider. The only requirement is that you use the inherits field in the profile section of the web.config.

E.g.:

<profile enabled="true" defaultProvider="AnyProfileProvider" inherits="YAF.Classes.Utils.YafUserProfile">

the_menace
2008-11-19T06:45:55Z
OK, that's what I thought..I just wasn't sure. Thanks for the clarification on this.
the_menace
2008-11-19T07:19:13Z
When I changed my web.config on both side to use my own provider, I get this error on my forums. My main site sits just fine.
I've never seen this error before. Do you know what may be causing this to happen?

Quote:


Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS0433: The type 'ASP.controls_forumsubforumlist_ascx' exists in both 'c:\windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\forums\9150c919\9e9028c7\App_Web_zzmbxqcc.dll' and 'c:\windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\forums\9150c919\9e9028c7\App_Web_-zt8flfi.dll'

JoelDKraft
2008-11-19T10:37:54Z
So I've been looking over YAF for a while, and as someone who is contemplating adopting the software, I would like to make some comments that are related to this thread. I'm going to give my rather blunt opinion, but this are general comments and concerns that someone like myself are having with reviewing ASP.NET software that we would like to integrate into an existing site. This is the first time I've tried to put all of these thoughts together, so bear with me.

I think what this thread shows most of all is that there are some design limitations of the ASP.NET provider model.

I'm actually a big fan of the concept of the Membership and Role providers, but the actual implementation was not done with flexibility and integration in mind. What is the real goal? to allow newbies the ability to easily make "secure" sites without actually having to make any decisions. Sure the concept of multiple providers is thrown in there, but I'm hard-pressed to see what utility that really has. And without any guidance, it seems like nothing but an afterthought.

Another limitation of these two providers is that they only operate in read/write mode. For those of us dealing with SSO systems and pre-built directories of roles that we don't necessarily want to expose willy-nilly to ASP.NET tools, there is no simple way to provide a basic version of the providers. Sure, I can put NotImplementedExceptions everywhere, but how do my applications know to avoid that code??

This could have been done by providing a very basic Membership/Role provider base class that does the absolute core functions (GetUser(), GetRolesForUser(), IsUserInRole(), and not a heck of a lot more), and using interfaces to tag modular functionality. Provide the existing SqlRoleProvider on top of that if you want to use all of the out-of-the-box tools. That way clients could query for the availability of that functionality and respond accordingly.

I can't even talk about some of the other garbage in there... if I've got an LDAP user database with 100K users in it, I'm not going to want to be using things like GetAllUsers() either! Especially when that list would be exposed to someone using a web application.

Then comes the dang Profile provider. Not only does this one come with the same "get it to work without thinking about it" functionality but it also contains detrimental "get it to work without coding it" functionality as well. The database of the default provider is the most unfriendly thing I have ever seen.

Although it might be easy to get your applications to use a single provider in this model, in order to get any real benefit out of this arrangement, you'd have to get them to agree on the naming of all of the properties, as well as their acceptable formats, and this probably is not going to happen. Since you really can't share data easily, and since an application like YAF is still probably providing is own database tables optimized for that application, why would you even bother trying to use another provider at all?

In this case, the providers should be named explicitly. (If you wanted everyone to use the same SqlProfileProvider, that's great, but listing them separately would at least allow you to specify different application keys.)

My bigger beef with the profile provider is applications relying on the automatic code-generation tools. If you are playing around with a simple site, then using <properties> is nice, but as you get more complex then that fragile configuration can definitely be an issue.

Unfortunately, this is a requirement of the framework since it gives no mechanism for a provider to supply a dynamic set of properties in code, and even if you don't care about nicely-generated class properties, the definitions are still used internally. It either has to be in web.config, or attributes of a class specified using the "inherits" attributes as described in this thread. The "inherits" thing is a nice idea, but why is a global profile configuration, instead of an attribute of the provider? What if I try to get two products that both want that value set to their own?

Personally, I would avoid the ASP.NET provider model here completely. I'm curious to hear why the person that started this thread would even want to use something other than what came with YAF.

If you have to use the framework, though, there may be some ways to get around it. If you have to implement a profile provider and therefore have to inherit from ProfileBase and ProfileInfo, you should be able to at least avoid calling their base functionality to get around all of this. I think I would try to get the profile explicitly using

The last thing that could be done, is to at least isolate things as much as possible by defining things in web.config in such a way that they don't conflict with other applications. For example, using a prefix on the property names which are then mapped to something better. You can then something calling ProfileManager.Providers["YAF"].FindProfilesByUsername() and use a wrapper class around the ProfileBase to make things easier.


<profile>
  <providers>
    <add name="YAF" ... />
  </providers>
  <properties>
    <group name="YAF">
      <add name="YAF_AIM" provider="YAF" ... />
      <add name="YAF_Birthday" provider="YAF" ... />
      ...
    </group>
  </properties>
</profile>


class YafProfile
{
   private BaseProfile _profile;
   public BaseProfile { get { return _profile; } }
   YafProfile(ProfileBase p) { _profile = p; }

   public string AIM
   {
     get { return (string)_profile.GetPropertyValue("YAF_AIM"); }
     set { _profile.SetPropertyValue("YAF_AIM", value);
   }  

   public string Birthday
   {
     get { return (string)_profile.GetPropertyValue("YAF_Birthday"); }
     set { _profile.SetPropertyValue("YAF_Birthday", value);
   }  

   ...
}



I think my favorite solution would be to using private reflection to populate the properties metadata programmatically, though, and still use some wrapper class to make it nicer. I wouldn't ever count on the provider to return anything but ProfileBase.

So what am I trying to get out of this rambling?? I'm trying to come up with a set of "best practices" for application developers who might be writing things that would be integrated into another ASP.NET site. Here is what I have:

1. Use the bare minimum number of functions of the providers that you need to do your job. Don't be tempted to use everything just because it is there!

2. If you are going to use the provider model, don't rebuild things that are already there, such as user or role maintenance. The ASP.NET tools are available to do administration of the default providers, and those of us with custom providers probably have our own tools already.

3. If you insist on ignoring 2, provide a configuration option in your application to indicate whether or not the Membership and Role providers are read only. If they are, disable editing functionality in your application.

4. Never assume that the default provider is for you to use, especially if your application requires a special provider. Use a well-known named provider, allowing that name to be configured if you think that is necessary. This would require you to do something like Roles.Providers["YAF"].IsUserInRole() instead of Profile.IsUserInRole() in the code. Really not the big of a deal in the grand scheme of things.

5. Do not use automatically generated profile properties through the <properties> if possible. Build your own functionality, if possible. If you must use the <properties> collection, prefix your values so they do not conflict with another application.

6. Do not require the "inherits" attribute of the <profile> configuration. It could conflict with another application.

Here are some other things I look for just in general.

7. Don't distribute code-behind files.

8. Uses a custom configuration section, or prefix all keys in appConfig with the application name.

9. If something goes into App_Data, put it in a sub-directory named after the application.

10. Don't require anything in App_Code.

11. Put things you want in a "known" location in a subdirectory of App_Resources named after the application.

I'd love to hear comments or any discussion about the providers as they relate to a project like this being integrated into an existing site. :)

Joel
daveburke
2008-11-20T04:29:51Z
Jaben wrote:

You can use any provider. The only requirement is that you use the inherits field in the profile section of the web.config.

E.g.:

<profile enabled="true" defaultProvider="AnyProfileProvider" inherits="YAF.Classes.Utils.YafUserProfile">



Jaben,

Thanks so much for the tip. This really came to my rescue on a new install last night!

Regards,
-Dave
Mek
  •  Mek
  • 100% (Exalted)
  • YAF Developer
2008-11-20T08:33:01Z
@Joel

Agreed, the asp.net membership, roles and profile have provided us with quite a headache hence the long process in development for 1.93 however the number one question with YAF is how do I integrate it and unfortunately for everyone this is MS's standard answer. I completely agree it is limited and wasn't conceived for multiple instances under the one application which is one of my primary concerns.
We are dealt the cards, and for interoperability believe that this is a necessity, and it has been warmly received by many users.

UserPostedImage 

"It's a case of RTFM.. the only problem being we don't have a manual!"

When I post FP:Mek in a topic, I'm leaving my footprint there so I can track it once I get into coding/supporting. (Yes I stole this off Ederon 🙂 )
the_menace
2008-11-20T19:22:51Z
I encounter another error. I'm getting a configuration error.
Quote:


This profile property has already been defined.



I defined my profile provider by using my own provider and inheriting the YafUserProfile.
Quote:


<profile enabled="true" automaticSaveEnabled="true" defaultProvider="StoredProcedureProfileProvider" inherits="YAF.Classes.Utils.YafUserProfile">
...



The configuration error is pointing below.
Quote:


<properties>
<add name="Gender" defaultValue="[null]" customProviderData="Gender;varchar;true"/>
<add name="FirstName" defaultValue="[null]" customProviderData="FirstName;varchar;true"/>
<add name="LastName" defaultValue="[null]" customProviderData="LastName;varchar;true"/>
<add name="DOB" defaultValue="[null]" customProviderData="DOB;datetime;true"/>
<add name="City" defaultValue="[null]" customProviderData="City;varchar;true"/>
<add name="State" defaultValue="[null]" customProviderData="State;varchar;true"/>
<add name="ZipCode" defaultValue="[null]" customProviderData="ZipCode;varchar;true"/>
<add name="Country" defaultValue="[null]" customProviderData="Country;varchar;true"/>
</properties>



What can I possibly do wrong here?
the_menace
2008-11-20T21:11:36Z
I'm using SqlStoredProcedureProfileProvider BTW as my custom profile provider if that matters. Will it still work?

It's complaining below about:
Procedure or function getCustomProfileData has too many arguments specified.
Quote:


<add name="StoredProcedureProfileProvider" type="SqlStoredProcedureProfileProvider" connectionStringName="cs" setProcedure="setCustomProfileData" readProcedure="getCustomProfileData" applicationName="app"/>



The getCustomProfileData as a stored procedure that gets my profile properties. (See below) Since it inherits the YAF custom provider, it might be passing in more parameters than necessary in the stored procedure. I think this is where the bulk of the integration problem is.

Quote:


<properties>
<add name="FirstName" defaultValue="[null]" customProviderData="FirstName;varchar;true"/>
<add name="LastName" defaultValue="[null]" customProviderData="LastName;varchar;true"/>
<add name="DOB" defaultValue="[null]" customProviderData="DOB;datetime;true"/>
<add name="City" defaultValue="[null]" customProviderData="City;varchar;true"/>
<add name="State" defaultValue="[null]" customProviderData="State;varchar;true"/>
<add name="ZipCode" defaultValue="[null]" customProviderData="ZipCode;varchar;true"/>
<add name="Country" defaultValue="[null]" customProviderData="Country;varchar;true"/>
</properties>

PHinett
2009-01-19T16:38:09Z
Hi, sorry to bring back an old topic...but it's pretty related to my question...

At the moment my application has A custom profile provider, membership provider and role provider which are working perfectly fine.

I have integrated YAF to work with my existing membership database (to a point).

I can login on my app, and if i view the forum it copies the user over to the yaf_users table and assigns them the correct groups.

However, my profile provider at the moment returns profile data from my custom database fields for the logged in user.

Here is my code in web.config...

<profile defaultProvider="CustomProfileProvider" inherits="YAF.Classes.Utils.YafUserProfile">
<providers>
<add name="CustomProfileProvider" connectionStringName="SiteSqlServer2" applicationName="/" updateUserProcedure="Account_UpdateProfile" getUserProcedure="Account_GetProfileById" type="House.Providers.CustomProfileProvider, __code" />
</providers>
<properties>
<add name="accountId" type="integer"/>
<add name="accountTypeId" type="integer"/>
<add name="email" type="string"/>
<add name="timeZoneOffset" type="integer"/>
<add name="timeZoneSet" type="integer"/>
<add name="RadioPlayerAutoPlay" type="integer"/>
<add name="siteId" type="int32"/>
</properties>
</profile>

As you can see i am inheriting from the YAF profile class. But my getUserProcedure and updateUserProcedure are only returning fields from my database for the above properties, not all the YAF profile properties.

So how can i return all the YAF profile properties as well as my own? Such as AIM, MSN etc...

Hope this makes sense, im pretty puzzled at this stage, i've battled through lots of problems to get this far and it's nearly there!

Thanks in advance!

Paul Hinett
http://www.house-mixes.com 

About Us

The YAF.NET is an open source .NET forum project. YAF.NET is supported by an team of international developers who are build community by building community software.

Powered by Resharper Donate with PayPal button

Project Twitter Updates

Copyright © YetAnotherForum.NET & Ingo Herbote. All rights reserved