Pages

Sunday, July 21, 2013

Programatically accessing your custom fields in VS2012 SimpleMembership

(This is the 3rd of a 3-article series, on using SimpleMembership along with customized fields)

Article 1: Visual Studio 2012 uses SimpleMembership as its new Membership Provider
Article 2: Adding custom fields to a VS2012 MVC4 SimpleMembership system
Article 3: This article.

In the previous article, I covered how to create custom Membership fields, such as a registered user's name or phone number. This article explains how to use these added fields programatically from within your project.

The key steps that we'll follow can be summarized as:

  1. Define the additional fields in the UserProfile class, so we can access them programatically (and get IntelliSense for them as well);
  2. Add them to the RegisterModel class, and various other places per details in the above article, so user's can supply values into them when registering;
  3. Run the program and go to the "Register" page (but do not create a new user yet. This will create the database tables (if they're not present);
  4. Modify the UserProfile table and add the required fields, such as FirstName and LastName;
  5. Tweak some code in the system-generated InitializeSimpleMembershipAttribute.cs program, to avoid an exception when the system makes a duplicate call to InitializeDatabaseConnection();
  6. Add code to the Index action method in the Home controller, to actually use the new fields we have added.
  7. Run the program, create a new user and supply data into the new fields, and test out everything.
Out of the above, steps 1 thru 4 are already covered in the article previously referenced. Please follow all the steps in that article, to make sure we've got the base correctly set up! So let us start from step-5.

NOTE: The above article only defined a single additional column - FullName. But here, we're using 2 additional columns - FirstName and LastName (in order to illustrate the use of multiple columns). In your own code you can, of course, create whatever columns you need to use, just making sure that they're consistent across the board.

(HEADS-UP: I have called my test project "SimpleMembershipCustomFields", so you'll see that namespace reference in the code given below. You'll need to replace that with your own project namespace reference.)

Tweak some code in the system-generated InitializeSimpleMembershipAttribute.cs program

The Websecurity method call already exists in the program. Enclose that code in an if() condition, else it sometimes gets called multiple times when doing various Membership-related tasks resulting an exception:

    if (!WebSecurity.Initialized)
        {
            WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
        }

Add code to the Index action method in the Home controller, to actually use the new fields

For demo purposes, I've simply added a text string derived from the newly added fields (FirstName and LastName).

First, in the "using" section, add the following namespace references:
// Customization: References to the additional field(s)
using WebMatrix.WebData;
using SimpleMembershipCustomFields.Models;
(substituting your own project's namespace reference instead of "SimpleMembershipCustomFields")

Next, add code in the Index action method to use the new fields. For your ready reference, I've simply copied over the entire Index() method. The code I've added here is all inside the IsAuthenticated condition; the rest is just the default generated program:

public ActionResult Index()
{
    ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

    if (WebSecurity.IsAuthenticated)
    {
        // The call to InitializeDatabaseConnection is mandatory before calling
        // any other WebSecurity method (test it by commenting it out)
        if (!WebSecurity.Initialized)
        {
            WebSecurity.InitializeDatabaseConnection(
                "DefaultConnection", "UserProfile", "UserId", "UserName", 
                autoCreateTables: false);
        }

        UsersContext uc = new UsersContext();
        UserProfile userProfile = uc.UserProfiles.Where(x => x.UserId == WebSecurity.CurrentUserId).FirstOrDefault();

        ViewBag.Message = "Hello, " + userProfile.FirstName + 
            "! Your last name is: " + userProfile.LastName + ". " +
            "Welcome, " + userProfile.FirstName + " " + userProfile.LastName + "!";
    }

    return View();
}

Something to note here is that we're (conditionally) calling the InitializeDatabaseConnection() method, although the last parameter is "false" (it was "true" in the call from InitializeSimpleMembershipAttribute.cs). If you're going to need this call from multiple places in your project, it may make sense to extract it out into its own separate method, with "autoCreateTables" as a param.

Run the program, and test out everything.

If all is well, you should be able to create a new user and supply values into the new fields, using the Register screen. The resulting Index page should look similar to the screenshot below. I've also added screenshots for the signed-out homepage as well as the database table contents.







Thanks for reading! Happy coding!

(This is the 3rd of a 3-article series, on using SimpleMembership along with customized fields)

Article 1: Visual Studio 2012 uses SimpleMembership as its new Membership Provider
Article 2: Adding custom fields to a VS2012 MVC4 SimpleMembership system
Article 3: This article.

2 comments:

  1. Excellent article. Thanks for being concise and to the point.

    ReplyDelete
  2. Those 3 articles contain all explanations I needed. Many thanks.

    ReplyDelete