Common Gotcha: Don't forget to <clear/> when adding providers

Recently I've helped a few people out who were having an issue with how they had added new Membership, Role, and Profile providers within their web.config file.  If you are ever going to add a provider declaration within your web.config file, please read-on to learn how to avoid a common gotcha.

Symptom:

You want to configure ASP.NET 2.0 to store your Membership/Role Management/Profile data within a remote SQL database.  To accomplish this you first use the aspnet_regsql.exe utility to provision the appropriate schema within the database.  Rather than override the "LocalSqlServer" connection string within your web.config file, you decide to register a new provider within your web.config file like below (note: the following registration has a bug - so don't copy/paste it):

      <membership>

            
<providers>
                
<add name="AspNetSqlMembershipProvider"
                    type
="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                    connectionStringName
="MyDatabase"
                    enablePasswordRetrieval
="false"
                    enablePasswordReset
="true"
                    requiresQuestionAndAnswer
="true"
                    requiresUniqueEmail
="false"
                    passwordFormat
="Hashed"
                    maxInvalidPasswordAttempts
="5"
                    minRequiredPasswordLength
="7"
                    minRequiredNonalphanumericCharacters
="1"
                    passwordAttemptWindow
="10"
                    passwordStrengthRegularExpression
="" 
                    applicationName
="/" 
                
/>
            </
providers>

      
</membership>

When registering the above provider you are careful to explictly set the applicationName property, and so avoid another really common gotcha.

When you run your application on a machine without SQL Express, though, you see some weird behavior.  You might get a SQL error like so:

An error has occurred while establishing a connection to the server.  When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)

You might also find that the web administration tool has problems connecting with your database and/or the roles/users you create within it aren't correctly saved in the database you configured above.

Cause of the Problem:

The root cause of the above problem rests in how the new provider was registered within the web.config file. 

The <providers> section within the web.config file is implemented as a collection, and so it is possible to register multiple providers at the same time (this is useful when you want to have some users authenticated using one Membership store, and others authenticated using a separate Membership store).

By default ASP.NET 2.0 registers a set of default SQL Express providers within the root web.config file on your machine that create a SQL Express database within your /app_data directory to store/manage membership/role/profile data when you first access it.  Because this is registered at the machine-wide level, all provider collections by default inherit this registration.  Unless you explictly <clear/> or override the inherited value, your application will have this default membership/role/profile provider registered.

Because the above web.config file simply added a new provider -- and didn't clear or replace the default provider registration -- the above application now has two Membership providers configured.  When you do a Membership.CreateUser() call in your code, ASP.NET will attempt to create the user in both membership databases.  If you don't have SQL Express installed on your system, the create-user attempt will fail for this database - which leads to the errors and/or weird behavior above.

How to Fix It:

Unless you wish to register multiple membership, role or profile databases (which is rare), you should always add an explicit <clear/> directive before your <add/> statements within your web.config file:

      <membership>

            
<providers>
                
<clear/>
                
<add name="AspNetSqlMembershipProvider"
                    type
="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                    connectionStringName
="MyDatabase"
                    enablePasswordRetrieval
="false"
                    enablePasswordReset
="true"
                    requiresQuestionAndAnswer
="true"
                    requiresUniqueEmail
="false"
                    passwordFormat
="Hashed"
                    maxInvalidPasswordAttempts
="5"
                    minRequiredPasswordLength
="7"
                    minRequiredNonalphanumericCharacters
="1"
                    passwordAttemptWindow
="10"
                    passwordStrengthRegularExpression
="" 
                    applicationName
="/" 
                
/>
            </
providers>

      
</membership>

This will ensure that your application doesn't inherit any default provider registrations. 

Note that you must do this for each provider declaration that you register.  So if you are adding providers for <roles> and <profile>, make sure you add the <clear/> directive in their providers section as well.

Hope this helps,

Scott

P.S. Click here to review other past ASP.NET Tips/Tricks, Gotchas, and Recipes.

Published Monday, November 20, 2006 11:22 PM by ScottGu

Comments

# |Absolute Value| &raquo; Tip of the Day

Tuesday, November 21, 2006 3:31 AM by |Absolute Value| » Tip of the Day

PingBack from http://www.rjb.za.net/2006/11/21/tip-of-the-day-2/

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 4:15 AM by vikram

hmm  I had a big problem when I used this with out application but later understood the system and updated it, Good trick

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 4:20 AM by Kirk Jackson

Good post Scott, this has caught me out before. Kirk

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 6:41 AM by Shreeman

I was thinking that when the final version ll be ships in , the default sqlexpress should be replaced by Sqlserver.But unfortunately it still points out to the default express one.Not only in asp.net but in many places i often forget to change the setting ..another example u can think of the p&p libraries..demos...why not just make those configurable from the groundsup rather asking for the changes to the user...justa  suggestion though..

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 10:52 AM by Steve Arthur

Wow, that helps a lot.  I was messing with a custom Membership provider in a remote database a while back.  I wasn't getting the error you describe, but I was seeing bizarre behavior that I was unable to explain.  I ended up making some changes in the application that I didn't want in order to make the system work as expected.  It makes perfect sense that the bizarre behavior was coming from the default provider.

Thanks Scott.

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 11:14 AM by Brennan Stehling

Scott,

I created a set of free controls (with all code) to make the setup for the membership and roles providers a little easier.  It provides a set of user controls to do much of what the website adminstration tool but it can be run on the public website in a restricted folder.  It also has some code to automatically set up a few roles and an admin user.

http://brennan.offwhite.net/blog/2006/09/15/free-controls-for-user-and-roles-management/

This code simply interfaces directly with the Membership API so it will work with any provider implementation.  Everything is explained on my blog.

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 11:18 AM by ScottGu

Awesome - thanks Brennan!

Scott

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 11:45 AM by Webdroid

What's the difference between using the remove and the clear property? Should I use remove, or clear?

Thanks.

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 11:55 AM by ScottGu

Hi Webdroid,

You can use the <remove/> directive to remove a specific provider.  <clear/> removes all of them.

You can use the same approach with just a single <remove/> directive if you want.  I generally recommend using <clear/> just because it ensures that you remove all of them.

Thanks,

Scott

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 1:34 PM by Ramon Durães

I finished discovering in practises, but now I am understanding better with its explanation.

thanks,

Ramon

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Tuesday, November 21, 2006 4:15 PM by James

Great timely gotcha...  I was scratching my head over just this very issue earlier today :-)

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Wednesday, November 22, 2006 5:17 AM by Petr

Why this method is prefered, rather then overriding the "LocalSqlServer" ?

Thanks

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Wednesday, November 22, 2006 10:40 AM by Brennan Stehling

Scott,

I am curious about an aspect which this configuration makes possible.  I know you can have more than 1 provider active, such as an XML in addition to a SQL provider.  Do you know any examples of this being done?  I have been kicking this around in the back of my head the past few weeks.

In one scenario you may have a mix of different user accounts and based on the user you may work with a different provider, such as LDAP, AD, or SQL.  I am interested in real world examples of this approach.

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Wednesday, November 22, 2006 7:31 PM by Arash

last month i switched hostings because of this!

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Saturday, November 25, 2006 6:34 AM by Shahed Khan

Hi Scott

I am a great fan of yours. I didn't know how to communicate with you... thought of positing here. Sorry if I have caused any inconvenience.

I am very excited to share with you that I have finally released the CommunityDrop1 for SmartCodeGenerator at GotDotnet.

http://www.gotdotnet.com/codegallery/codegallery.aspx?id=cdb291ef-b7ee-4dec-aa29-6ba8d7790540

SmartCodeGenerator is an Asp.Net2.0 website application and is a full fledged template based code generator that allows you to generate code for any text language. Templates are written in Visual Studio as asp.net UserControls. The code generation can be dynamically customised by using properties. SmartCodeGenerator Framework reads the asp.net Profile Object specified in web.config and generates UIProperty. You can define any serializable .Net Object Type as properties of asp.net Profile that has a UIProperty. At this stage it support common types such as string, int, boolean and a ScTableSchema type (which represents SQL Server provides information about database tables). But this is extensible and UIProperty for any .Net types are very easy to write.

The SmartCodeGenerator Project is simply an asp.net website project, and SmartCodeGenerator Templates are asp.net UserControls so no need to learn any new technologies. Codes are written as you would normally write for a asp.net application.

The current feature list of SmartCodeGenerator includes:

The total development of templates are done in VS2005.

Extensible Template Generation Engine.

Sql Server schema discovery API

Writing asp.net2.0 website application so no need to learn anything new

Generate text base output.

Fully Customized template based code generation.

The entire development life cycle of creating custom templates using SmartCodeGenerator is done using VS2005 and you really write am asp.net website. So during the generation of template intellisense, compilation, debug, sourceview, designview, codebehind file and all other features of VS2005 comes free.

After you play with this great framework for 5 min, I think you will agree with me saying "Code generation has never been this easy".

For Quick Examples and get a overview of the idea please check...

http://geekswithblogs.net/shahed/archive/2006/11.aspx

and if you like the concept please blog about it.

shahed.khan@gmail.com

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Sunday, November 26, 2006 2:35 PM by ScottGu

Hi Brennan,

I'll put it on my list of things to blog about (warning - the list is long so I'm not 100% sure when I'll get to it!)

In a nutshell, you can control which provider is the "default" provider by setting the "defaultProvider" property that is on the <membership>, <roles>, <profile> elements in web.config.

Programmatically you can the choose a different provider by accessing the "Providers" collection on the Membership/Roles API.  For example:

       Membership.Providers["otherprovider"].ValidateUser(username,

password)

Note that the "otherprovider" name is determined by the <add/> element in your web.config file (where you give each provider a name).

Hope this helps,

Scott

# re: Common Gotcha: Don't forget to <clear/> when adding providers

Sunday, November 26, 2006 2:44 PM by ScottGu

Hi Petr,

Simply overriding the "LocalSqlServer" connection-string also works.  The one benefit of redefining the provider is you can also go ahead and change any of the provider properties at the same time.

Hope this helps,

Scott

# links for 2008-06-20 &laquo; dstelow notes&#8230;

Friday, June 20, 2008 7:38 PM by links for 2008-06-20 « dstelow notes…

Pingback from  links for 2008-06-20 &laquo; dstelow notes&#8230;