views:

67

answers:

2

Hello, I am creating a custom SqlMembershipProvider class to add some enhanced functionality to the base class. I'm getting caught up on handling the connection string, though. How can I read the Connection String Name from the configuration and make that available to the rest of the methods?

Right now I have:

public override void Initialize(string name, NameValueCollection config)
        {
            base.Initialize(name, config);

            _ConnectionStringName = config["connectionStringName"];
        }

But in other methods, the _ConnectionStringName variable is null:

SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[_ConnectionStringName].ConnectionString)

What is the proper way to store the Connection String Name so it is available globally in my custom membership provider?

Thanks!

+1  A: 

ProviderBase will throw a ConfigurationException if there are any entries left in the config collection by the time it get's it so each provider removes it's configuration entries before calling base.Initialize.

The issue, as you have found as a result of this answer is that you must get your values before calling base.Initialize.

Sorry, I missed that at first glance.


The rest of this post is historical and while technically correct misses the salient issue here as enumerated above.

First - try WebConfigurationManager.ConnectionStrings.

WebConfigurationManager handles applying the hierarchy of web.config all the way from your windows\microsoft.net\framework\2.0xxxx\web.config all the way up to your app.

This behaviour is not present in ConfigurationManager, which typically deals with machine.config to app.config.


If this does not solve your problem you must be overwriting the value elsewhere in your code, if indeed _ConnectionStringName is being properly assigned in Initialize.

First, set a breakpoint and ensure that _ConnectionStringName is being set as expected.

Then locate all references to the field and ensure that you do not have a bug.

This is assuming, of course, that _ConnectionStringName is a private field. If it is not, make it so and look for your compile error.

Sky Sanders
I'm aware of how to retrieve the connection string from web.config. My specific question is in regards to retrieving the Connection String Name attribute from Initialize and making that available to the rest of my methods. I set breakpoint and _ConnectionStringName is getting set correctly, but it's null by the time my I call it in another method.
Mike C.
@mike - then you are either referencing a different member or the member is being overwritten. With the given information there are no other possible explainations.
Sky Sanders
I'll check it further in depth. I was very confused also and thought there was a gotcha somewhere I wasn't aware of.
Mike C.
I was setting it after the call to base.Initialize. I moved it to before and it works properly now. Thanks!
Mike C.
@mike - if you look at the source for SqlMembershipProvider you will see that it removes the values it expects from the collection before calling base. If there are any left an error is thrown. As for this question, while I missed it at first glance, I unintentionally answered it in the other question. I am going to update the answer with the problem with your code. You should leave it as is so others can see the problem and solution.
Sky Sanders
Interesting. I'll have to remember that for future applications.
Mike C.
A: 

Not sure if this helps, but I was having a similar issue in needing to override the connectionstring in a sub-class of SqlMembershipProvider.

This idea is not my own - I found it in the comments section of this forum posting: http://forums.asp.net/p/997608/2209437.aspx

public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name, config);
string connectionString = ...what you want your connection string to be, so config["connectionStringName"]...
// Set private property of Membership provider.
System.Reflection.FieldInfo connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
connectionStringField.SetValue(this, connectionString);
}

My apologies - I've never posted here before, so the formatting may be sub-par!

Gregg
Thanks for the comment. However, I don't think the posted code will work. It seems the base.Initialize method clears the config values. This is the original issue I was having.
Mike C.