Welcome to MSDN Blogs Sign in | Join | Help

saurabhd's musings

Saurabh Dasgupta works for Microsoft Consulting Services. - '640kb ought to be enough for anybody'
Invoking SqlMembershipProvider from a Windows forms application

 The abstraction provided by MembershipProvider base class is a very powerful concept in ASP.NET 2.0. It simplifies the management of user information by providing a neat layer.

ASP.NET 2.0 provides the SqlMembershipProvider class and the aspnet_regsql command line utility to create the database user management database. My customer was building a hybrid application, which was mainly ASP.NET 2.0, but there were a few forms implemented using Windows forms. The question  arose as to how a windows forms login form can be created that will use the SqlMembershipProvider.

This is what I did.

  • Created a new windows forms application. Add an app.config file.
  • Added the following section to the config file.
  • Ensure that the settings match with your database (which would have been created using aspnet_regsql.exe tool)

  <configSections>
    <section name="connectionStrings" type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" />
  </configSections>

  <connectionStrings>
    <add name="mydb" connectionString ="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Helloworld;"/>   
  </connectionStrings>

  • Wrote a factory method to instantiate and correctly initialize the provider. ASP.NET 2.0 reuses a single instance of the provider for servicing all requests.

    class MembershipProviderFactory
    {
       static public MembershipProvider Create()
        {
            string cn="";
            System.Configuration.Configuration config=
            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (config == null ) throw new ConfigurationErrorsException ("Could not read config file");

            //searching for the connection string element with the zero th index.
            ConnectionStringsSection cnstringssection;
            cnstringssection = config.ConnectionStrings;
            if (cnstringssection.ConnectionStrings.Count == 0) throw new ConfigurationErrorsException("connection string information not found in config file");

            ConnectionStringSettings cnsettings;
            cnsettings = cnstringssection.ConnectionStrings[0];
            cn = cnsettings.ConnectionString;
 
            if (string.IsNullOrEmpty (cn))
            {
                throw new ConfigurationErrorsException("connection string information (cn) not found in config file");
            }

            SqlMembershipProvider prov = new SqlMembershipProvider();
            NameValueCollection vals=new NameValueCollection ();
            vals.Add("name", "sql");
            vals.Add("connectionStringName", "mydb");
            vals.Add("applicationName", "MyApplication");
            vals.Add("maxInvalidPasswordAttempts", "100");
            prov.Initialize("sql", vals);
            return (MembershipProvider)prov;
        }
}

  • The applicationName property should match the web.config settings in the ASP.NET application.
  • The code for validating the user credentials is as follows

            System.Web.Security.MembershipProvider    memprov;
            memprov = MembershipProviderFactory.Create();
            if (memprov.ValidateUser("user1", "pass@word1") == false )
            {
                MessageBox.Show("Invalid username or password");
            }
            else
            {
                MessageBox.Show("User credentials verified");
            }

  • ..The important thing to be remembered here is that SqlMembershipProvider expects the <connectionStrings> section in the configuratin file for connecting to Sql server. I would be very glad if somebody can find out how SqlMembershipProvider can be initialized without the need for <connectionStrings> section in the app.config file.

I do believe that this is not the best way to solve my customer's problem. A better way would be to expose web services for the required functionality and let the windows forms app connect to this service using WSe 3.0/WCF and passing the user name token along with the method invocation. This would be more secure because the connection string is not exposed to the caller and it would be n-tiered as well.

 

Posted: Wednesday, August 02, 2006 1:41 AM by Saurabh Dasgupta

Comments

James said:

Have you tried using the default localsqlserver in the machine.config file of the asp machine?

# January 5, 2009 8:44 PM

Djuffin said:

var a = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).ConnectionStrings as ConnectionStringsSection;

a.ConnectionStrings.Add(new ConnectionStringSettings("asd", "asdas"));

# March 11, 2009 1:47 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker