Zoki's Blog

When future comes first! iDevolution

Using the built in ASP.NET Membership provider in Windows Forms or Console applications

Creating and validating users

One of the features in ASP.NET 2.0 is the Membership and Role providers. These providers represent nicely designed system that allows us to handle the storage of user information any way we like and all we need to do is to create the appropriate providers and configure the application to use them. The abstraction provided by MembershipProvider base class for example, is a very powerful concept in ASP.NET 2.0. It simplifies the management of user information by providing a neat layer. Even though these providers are created for use in ASP.NET it will be very nice if we could use the same providers in Windows Forms or Console applications. As we know, ASP.NET 2.0 provides the SqlMembershipProvider class and the aspnet_regsql.exe command line utility to create the database for the required user management. This database could be standalone database that will hold only the membership and roles data (there are more things that we could do with it like personalization but this is not the scope in this blog) or part of our custom application database.

In this first part I will discuss how to create and validate users and I will use a standalone database just to show you how easy the integration of the ASP.NET 2.0 Membership and Roles provider in Windows Forms/Console applications.

Let’s create a very simple console application with user management. At the begging just create one Console application (C# or VB does not matter) and add reference to System.Web assembly in the project and the using statement as follows:

using System.Web.Security;

Now add the following code to Main() method:

if (Membership.ValidateUser("Zoki", "Password"))
{
    Console.WriteLine("User valid.");
}
else
{
    Console.WriteLine("User invalid.");
}
Console.ReadLine();


You can try and run the application at this point. Please not be surprised when the application reports that the user is invalid, after all, the username and password that we are trying to validate, don't exist in the database. To check if this validation works we should create user and validate the same. Add the following code above the ValidateUser call:

MembershipCreateStatus status = new MembershipCreateStatus();
Membership.CreateUser("firstuser", "p@ssword", 
"zoki.zlatanov@gmail.com", "question",
"answer", true, out status); Console.WriteLine(status);

Run the application now...

Works, right?

So where is the magic here? We haven’t done anything to configure the membership provider or told it which database to use?
The secret is that the membership provider checks for, and creates if needed, a new directory under the application directory named App_Data with a SQL Express database ASPNETDB with the required structure. This database is then used to store the user information. To see the database click on the Show All Files button in the explorer, Open the bin/Debug folder and you will see an App_Data folder with the ASPNETDB.MDF database inside of it.
In this moment we have done very little work and in the meantime we have a working application that can register and validate users. If we try to execute the code again we will get DuplicateUserName status but the validation of the user (the ValidateUser method) will pass again. The problem that we are facing now is the bunch of information that we need to pass to the CreateUser method just to create one. For example supplying the password question and answer in Windows Forms application is not quite common task. Fortunately the Membership.CreateUser method has an overload that accepts only 2 parameters which will do our job. Those parameters are naturally username and password. Lets add the following code

Membership.CreateUser("seconduser", "p@ssword1");

instead

Membership.CreateUser("firstuser", "p@ssword", 
"zoki.zlatanov@gmail.com",
"question", "answer", true,
out status);

Run the application...
You are getting an exception System.Web.Security.MembershipCreateUserException with the message "The password-answer supplied is invalid.".
To avoid this we should set the Membership properties. There is one way to do that and that is by adding these settings to application app.config. Because we still don't have one in our application lets add it. Now we need to add the following to the bottom of the <configuration> section:

<system.web>
  <membership>
    <providers>
      <remove name="AspNetSqlMembershipProvider"/>
      <add name="AspNetSqlMembershipProvider"
           type="System.Web.Security.SqlMembershipProvider, System.Web,
           Version=2.0.0.0, Culture=neutral,
           PublicKeyToken=b03f5f7f11d50a3a"
           connectionStringName="LocalSqlServer"
           enablePasswordRetrieval="false"
           enablePasswordReset="false"
           requiresQuestionAndAnswer="false"
           applicationName="/"
           requiresUniqueEmail="false"
           passwordFormat="Hashed"
           maxInvalidPasswordAttempts="3"
           minRequiredPasswordLength="4"
           minRequiredNonalphanumericCharacters="0"
           passwordAttemptWindow="10"
           passwordStrengthRegularExpression="" />
    </providers>
  </membership>
</system.web>

This section is very familiar cause it comes from a web application config file. Maybe it seems little strange but as I've mention in the beginning the Membership provider was written by the ASP.NET team for ASP.NET use.  So what does this section actually do? This configuration block removes the default membership provider as defined in the machine.config and adds the same one but this time with all our settings in place.
Try to run the application now... The user will be created without any problems.

In the next part I will show you how to add roles and set users roles.

Until next time... Happy coding

 

Comments

Coedayovasy said:

Hello

Nice site!

Bye

# October 1, 2008 4:00 AM

rahul said:

Thanks a lot

its very useful

# October 27, 2008 9:41 PM

Gary Woodfine said:

Excellent.

This helped me answer a question. When I sat down and thought about it the answer seemed obvious, but your post helped me confirm it and supplied me with a little bit of detail I was lacking.

Thanks for taking the time to post this.

# February 18, 2009 8:30 AM

Zoki said:

I am glad I can help...

# February 19, 2009 12:50 PM

... said:

Gut!

# March 1, 2009 8:00 PM

... said:

Sehr wertvolle Informationen! Empfehlen!

# March 13, 2009 9:38 AM

Stan said:

I have just recently been discovering the power of the Membership provider functionality, but I'm missing one huge piece of the puzzle.  I've been looking all over and can't find the answer.  How can I get some kind of ID of the person logged in?  I want to create tables in a seperate database that hold information for each specific user that registers at my site.  I'm looking for an integer or even a guid from the membership system, so when a page loads I can go get information about the current user from my database.  There must be some unique id associate with each new account in the membership system.  I wouldn't think I would want to use UserName because I would think that a username could potentially change at some point.

What am I missing?  Thank you for any tips you can provide.

# March 31, 2009 11:46 AM

ivanacev said:

Hi Stan,

you are right, there is an unique id associated with each account in the membership system. In the aspnet_Users table there is a UserID column (from type uniqueidentifier) which is the PK for this table. You can use the aspnet_Membership_FindUsersByName SP to retrieve the UserID if you know the UserName.

# April 1, 2009 12:41 AM

Zoki said:

Yes

As ivanacev said use this piece of code to get the currently logged user ID:

if (Page.User.Identity.IsAuthenticated)

{

     object userId = Membership.GetUser().ProviderUserKey;

}

# April 1, 2009 5:53 AM

ChabrellIgan said:

God dag! Kan jag ladda ner en bild fran din blogg. Av sak med hanvisning till din webbplats!

# April 20, 2009 4:38 PM

AndrewBoldman said:

Hi, good post. I have been wondering about this issue,so thanks for posting.

# June 4, 2009 1:52 PM

Rob said:

Exactly what I was looking for. I knew it had to be possible. Thanks for posting.

# June 5, 2009 10:24 PM

anairat said:

if we need to edit the attributes that we entered with createuser() such as the email address for a specific user, should we still using Membership class?

# September 17, 2009 2:28 AM

Zoki said:

Yes you should still use Membership class.

# October 19, 2009 1:34 PM

ricky said:

If you are using this in winforms with a remotely hosted database.... would you need to membership.createuser each time a client runs the windows forms application on their computer?

Example:

Employee opens up the winform app on his pc, the winform app then queries the sql server database for ALL user accounts and returns them across the network to the employees pc.  Employees PC proceeds to call membership.createuser for each user record in the database.  Once done.... Employee can proceed to login with credentials against the membership provider.

Is that how this is supposed to function using winforms?  Is there a better way to create the users in the membership provider server side so the client doesn't ahve to go through the agony of collecting the entire users table?

Thanks!

# December 10, 2009 3:46 AM

Iivari Mokelainen said:

Hi! Thanks for posting this!

I didn't have any problems with the Membership per se, but some things returned no results and some exceptions, and all I needed was applicationPath="/" in app.config which I saw in your code. Thank you - saved me some nerves.

# December 22, 2009 7:54 AM

ciberado said:

Great info, thanks a lot :-)

# January 31, 2010 9:58 AM

Zoki said:

@ricky:

I really do not understand but Membership.CreateUser() method is called only when we want to create new user so I don't see why you should go through collecting the entire users table.

# February 4, 2010 12:04 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)