Sample Code for Custom ASP.NET Profile Provider

Until The ServerSide .NET can post the sample code, I am posting it here

- Sample Code

Thanks to Thomas Carpe for reminding me that I posted the wrong code!  Fixed!

Comments:

Okay, this is probably not related directly to your profile provider, but is more like a "general profile provider" issue.

The problem is that using a custom profiler results in an Exception with this message.

"The profile default provider was not found"

Attaching with the debugger proves that neither the constructor nor the Initialize method of the provider are ever called, and the exception is thrown from ProfileBase.Create(userName) the first time you try to attempt to read the Profile object on the Page.

If I switch back to a provider in the System.Web namespace (by changing the value of defaultProvider) then everything works fine, but not the way I need it to, obviously.

I have tried putting the class in the web project's Bin folder, in the GAC, and also in the App_Code folder - same results.
The class is strongly named.

Here's the relevant part of web.config:

<profile defaultProvider="AspNetSqlProfileProvider" automaticSaveEnabled="False" >
<providers>
<clear />
<add name="AspNetSqlProfileProvider" connectionStringName="AspNetSQLConnectionString" applicationName="/" type="Colossus.Web.Profile.SearchableSqlProfileProvider, Colossus.Tools, Version=2.0.1.0, Culture=neutral, PublicKeyToken=b80525f71c2ba3d8"/>
<add name="OriginalSqlProfileProvider" connectionStringName="AspNetSQLConnectionString" applicationName="/" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
...

I have also tried:

<add name="AspNetSqlProfileProvider" connectionStringName="AspNetSQLConnectionString" applicationName="/" type="Colossus.Web.Profile.SearchableSqlProfileProvider, Colossus.Tools"/>

and simply:

<add name="AspNetSqlProfileProvider" connectionStringName="AspNetSQLConnectionString" applicationName="/" type="Colossus.Web.Profile.SearchableSqlProfileProvider"/>

What I would really like to know is has anybody found or come up with a clear list of the requirements needed to get a custom profile to run? Say for instance is it okay to put it in the Bin folder, or does it need to be in the GAC? Microsoft documentation is comprehensive, as always. ;-)

I will let you know if I learn anything more.

Thanks in advance,

File this one under “its amazing what a good night’s sleep can do for your brain.” The solution turned out to be a “well, duh” moment, but the way I came to it might help other troubleshoot similar problems.

The issue turned out to be that when inheriting from another provider class, you shouldn’t override the Name property of your provider. Thanks to the total lack of docs, I assumed Name was a string representation of the class name. Wrong! It holds the name you give the provider in web.config. So, if you override the name, then of course System.Configuration can’t find it in the ProverManagers.Providers collection and promptly barfs with an always helpful (and detailed) message.

How I came to figure this out was by breaking into my code at the start of the Page_Load event. Before running, I switched my web.config to a default provider that I knew would work (System.Web.Profile.SqlProfileProvider) I was able from there to put a watch on the ProfileManager object, and browse into Provider and the Providers collection. How strange that all my providers were in fact there, but I couldn’t set it as the default? Anyway, long story short, if you dig into the base class underneath the custom provider, you can see how it uses the Name property and how I was replacing the correct name with a hard-coded string. Don’t try this one at home, kids!

You also get a peek at a ton of internal properties like the ones mentioned in the sample/article. However, it appears that commandTimeout doesn’t work and that in this implementation it ends up being useless, since the timeout property of SqlConnection objects appears to be read only. That’s okay because the default timeout is probably acceptable, but I’d be interested to know how to overcome this limitation.

I noticed that the time out seems to be ignored by the SQL Server Profile Provider. But you could try putting it into the Connection String instead (where the Sql provider should allow it).

I noticed some other minor bugs in the code as well. When you deserialize, you don't do the same override of the property.SerializeAs that you do when you serialize (the one that overrides the ProviderSpecific type if it is a primitive of string). Wouldn't the result be that such properties can be written but not read? Also, every so often you'll clear IsDirty for some serialization types - but not others. I assume that's just an oversight. I've been working on asome additional enhancements, as I am sure you're doing also. Send me an e-mail and I'll reply with my revised code attached to it. :-)

There might be a bug or two that slipped by my stealth QA staff (me). I'd love to see any enhancements/bugs you find so I can address them. Thanks!

Thomas, just to clarify, the Name you are talking about, is that the overriden ApplicationName? I'm getting that same error "The profile default provider was not found." I tried commenting out the override ApplicationName out but that isn't working either.

How about searching for multiply properties? with and/or between them, this one only search for One property. Eg. firstname=anders and lastname=hessel and so on....


 



 
Save Cancel