Implementing Password Reset in MVC 4 EF Code First using Simple Membership – Part 1

Visual Studio Logo
So everyone by now knows that I’m a big fan of Entity Framework Code First approach: I’m a developer and not a DBA so I appreciate anything that allows me to abstract my task away from the SQL world. A previous post explained how to setup an MVC 4 EF-Code First application. That application comes with a baked in user authentication system using Simple Membership; however, it lacks one necessary function for it to be truly usable–a password reset.

I’m not sure what the Microsoft guys were thinking when they created the starting sample application without a password reset since Simple Membership has all the functionality to easily create one. Perhaps it’s a liability thing.

Throwing caution to the wind, this post will explain–step by step–all that is necessary to create a usable password reset using the framework that’s already there.

Part I – Create an MVC Application with Email in the User Profiles

The following steps show how you can add email (or any other parameter) to the UserProfile of Simple Membership. This useful especially when you want to get more information on your users. For example, you may want their email, mobile, twitter, facebook, etc. this may be useful to have in either the UserProfile table or table(s) associated there. Either way, the following should help you understand on the required steps to make such changes. It’s also happens to be the preliminary step to implementing a password reset; after all, we’ll need the users’ email to send them their reset link!

Step 1 –  Create a MVC 4 Razor Application

I call my application “PasswordResetApp” but you call it whatever your want. Ensure that you are using the sample application that’s provided with VS2012 without playing around with any of the settings.

Step 2 – Adding Email to the UserProfile Class

Before we even create anything, we’ll need to ensure that our account stores users’ email, which we’ll use to send out a password reset link. This is a little tricky because of how Simple Memberships is setup.

First, we’ll need to turn off the default way that Simple Membership is initialized by removing the following line from AccountController:

[Authorize]
//[InitializeSimpleMembership] /**COMMENT OUT OR DELETE THIS LINE**/
public class AccountController : Controller
{

Next we’ll need to create a Database Context (step 3) of the setup tutorial. Here you can add your model (but do it later). For now, we’ll just add the UserProfile object. Create a new class that extended the DbContext class called MyDbContext and add the UserProfile object (I put this in a new file called MyDb.cs in Models).

public class MyDbContext : DbContext
{
   public MyDbContext(): base("DefaultConnection") {}
   public DbSet<UserProfile> UserProfiles { get; set; }

Next add the Email string object to the UserProfile class of AccountModel.cs:

public class UserProfile
 {
   [Key]
   [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
   public int UserId { get; set; }
   public string UserName { get; set; }
   public string Email { get; set; }  // Add this
 }

We’ll need to initialize Simple Membership (since we turned it off) when we run our db initialization code. So create a new class DbInit that inherits from DropCreateAlways and put it in your Models folder. This is step 5 of the setup tutorial. I put this in the DbInit.cs in Models:

public class DbInit : DropCreateDatabaseAlways<MyDbContext>
{
    protected override void Seed(MyDbContext context)
    {
       SeedMembership();
    }

    private void SeedMembership()
    {
       WebSecurity.InitializeDatabaseConnection("DefaultConnection",
          "UserProfiles", "UserId", "UserName", autoCreateTables: true);
    }
 }

By putting the SeedMembership() function at the end of all your Db Seed code, we ensure that Simple Membership is initialized after DB creation.

Next we simply initialize the database and ensure that it is run when the app is started. I do this at the end of the Application_Start() function in Global.asax:

Database.SetInitializer<MyDbContext>(new DbInit());
new MyDbContext().UserProfiles.Find(1); // This ensures that DbInit is run.

Step 3 – Modifying the Registration View to Accomodate for Email Input

First add the email string to the RegisterModel so you can pass in the information and validate the form (at this point you can have two email inputs for mis-type validation similar to password entry, which is what I do here). This is what I add to the RegisterModel class of AccountModels.cs:

[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email")]
public string Email { get; set; }

[DataType(DataType.EmailAddress)]
[Display(Name = "Email")]
[Compare("Email", ErrorMessage = "The emails you've entered do not match.")]
public string ConfirmEmail { get; set; }

Then we’ll need to edit the ~\Views\Account\Register.cshtml view to account for our new variable. I add the following right below the list <li> element:

 <li>
   @Html.LabelFor(m => m.Email)
   @Html.TextBoxFor(m => m.Email)
 </li>
 <li>
   @Html.LabelFor(m => m.ConfirmEmail)
   @Html.TextBoxFor(m => m.ConfirmEmail)
 </li>

Next we’ll need to edit the controller for Register post-back  ([HttpPost]). This is the Register(RegisterModel model) function in AccountController.cs. All you need to do is modify the following line:

WebSecurity.CreateUserAndAccount(model.UserName, model.Password);

To:

WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email });

And now we have a working application that gathers the user’s email upon registration and then stores it in the UserProfile object and the UserProfiles database.

End of Part I

There’s still a whole lot more to implement the password reset so hold tight for Part II of this post where I will provide the source files of my PasswordResetApp, the references (useful links), and a graphical summary much like I did in the setup tutorial.

PART 2 NOW AVAILABLE

Comments 10

  1. This is exactly the 2nd posting, of your website I actually checked out.
    Although I personally enjoy this specific one, “Implementing Password Reset in MVC 4 EF Code First using Simple Membership –
    Part 1” the best. Take care ,Antje

    1. Post
      Author
        1. Post
          Author

          Hey Phil!
          Part II is now out. I didn’t have time to proof read so I hope it’s okay. Also I was coding the application as I wrote the post, do you think it would help people if I uploaded a copy of the source code?
          Cheers,
          Dominik

          1. Dominik,

            Thank you again for the efforts you have invested here; your demo/tutorial has saved me a lot of headaches in the development process of implementing a password reset.

            The source code is all laid out in an understandable way, however I do believe that having the source code available to download would further enhance the understanding of the concept on the whole.

            Thanks again,
            Phil

    1. Post
      Author

Leave a Reply

Your email address will not be published. Required fields are marked *