However, there are a few issues to be aware of if you build an application on top of the existing code in the AccountController.
The InitializeSimpleMembershipAttribute (let’s call it ISMA) is part of the code generated by the MVC 4 Internet template. ISMA exists to provide a lazy initialization of the underlying providers, as well as potentially create the database for storing membership, roles, and OAuth logins. You’ll find it decorating the AccountController as an action filter, so it can jump in and initialize all the bits before the controller starts to interact with the security related classes.
[Authorize]
[InitializeSimpleMembership]
public class AccountController : Controller
{
// ...
}
As an action filter, ISMA hooks into OnActionExecuting to perform the lazy initialization work, but this can be too late in the life cycle. The Authorize attribute will need the providers to be ready earlier if it needs to perform role based access checks (during OnAuthorization). In other words, if the first request to a site hits a controller action like the following:
[Authorize(Roles="Sales")]
.. then you’ll have an exception as the filter checks the user’s role but the providers aren’t initialized. We’ll talk about concerns over the exception message details later.
My recommendation is to remove ISMA from the project, and initialize WebSecurity during the application start event.
The MVC 4 Internet project template uses EF code-first classes to manage user profiles, so it includes a DbContext derived class (UsersContext) and a UserProfile entity, both of which are defined in the Models\AccountModel.cs file.
If you plan on customizing the UserProfile class, make sure you let the application create the database for you. You can see the database creation code in the ISMA also.
If you create a database yourself, make sure to include all the tables needed for the WebSecurity class. There are not scripts published that I have found, but you can always generate DDL scripts after the application runs.

If you create an empty database and run the application to let WebSecurity create its own tables, it will not include any of your user profile customizations (it will only do that for you if the database doesn’t exist).
There is a strange tension in a new application because it’s not clear who is responsible for getting all the pieces to work together. WebSecurity can create the database schema it needs to operate, but can miss creating something you add to the UserProfile entity, which is code you can customize, but you wouldn’t know that at a first glance.
If you are using the Entity Framework for an application, my recommendation is to remove the DbContext derived class from AccountModel.cs and take ownership of the UserProfile class. You’ll need to fix places in the AccountController that are looking to use the context class, but replace those pieces of code with your own context class.
If you are not using the Entity Framework, you’ll want to remove the DbContext derived class in any case.
Because the Internet project template includes an Entity Framework DbContext class in the project, if you add your own DbContext to the project and try to enable EF migrations, you’ll be greeted with an error.
PM> enable-migrations
More than one context type was found in the assembly.
To enable migrations for [Context], use Enable-Migrations –ContextTypeName [Context].
The problem is easy to solve. As the error states, you can use the –ContextTypeName flag to specify your context class name. Note that you can only have migrations for one context in a project, so if you want to have migrations for both contexts you’ll need to move one to a different project. Again, my recommendation is to just remove the existing UsersContext the Internet project template creates, and take ownership of the user profile in your own context.
The previous ASP.NET membership providers were easy to work with from the Seed method in an EF migrations class. With this new approach you need to perform some additional configuration steps. I covered these steps in a previous post: “Seeding Membership and Roles in ASP.NET MVC 4”.
It’s possible to run into an exception message like the following (like when the ISMA code runs too late):
You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class. This call should be placed in an _AppStart.cshtml file in the root of your site.
We don’t use an _AppStart.cshtml file in ASP.NET MVC, so look to add code to Application_Start in global.asax.cs instead.
A few people have written me to ask if the AccountController created by the Internet application template is the future of ASP.NET MVC coding. A representative sample appears below:
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Specifically, people are asking about the number of static method calls through WebSecurity and trying to figure out the impact on testing and extensibility, as well as the impact on impressionable young minds who might read too much into the code.
I’ve assured everyone the future is not full of static methods. Or, at least not my future.
In some upcoming posts we’ll explore an alternative approach to membership, roles, and OAuth in ASP.NET MVC 4, and see if there is an approach that is simple, testable, and extensible enough to work with more than a relational database for storage.
If you are new to ASP.NET MVC you might not know about ELMAH and MiniProfiler. These are two distinct OSS projects that you can easily install with NuGet, and both provide valuable debugging and diagnostic services. Scott Hanselman has blogged about both projects in the past (see NuGet Package of the Week #7, and #9), but this post will highlight some of the updates since Scott's post and still provide a general overview of the features for each project.
ELMAH gives you "application-wide error logging that is completely pluggable". In other words, you can easily log and view all the errors your application experiences without making any changes to your code. All you need to get started is to "install-package elmah" from the Package Manager Console in Visual Studio and ELMAH will be fully configured and available. Navigate to /elmah.axd in your application, and you'll see all the errors (this will only work for local requests, by default).
ELMAH will keep all the errors in memory, so an application restart will clear the log. If you want the error information to stick around longer, you can configure ELMAH to store information in a more permanent location, like inside of a database. The elmah.sqlservercompact package will add all the configuration you need to store the error log in a SQL Compact database file inside the App_Data directory of the app. There are also packages to log errors to SQL Server (elmah.sqlserver), Mongo (elmah.mongodb) and more. Most of these packages require you to go into the web.config file to configure simple connection string settings, and possibly setup a schema (see the files dropped into App_Readme for more details).
For ASP.NET MVC projects you might want to start by installing the elmah.mvc package. The elmah.mvc package will install an ElmahController so you can view the error log by visiting the /elmah URL. More importantly, elmah.mvc will install an action filter to log errors even when the MVC HandleErrorAttribute (the one that most applications use as a global action filter) marks an exception as "handled". The HandleErrorAttribute marks exceptions as handled and renders a friendly error view when custom errors are enabled in web.config, which will usually be true when an app runs in production. These handled exceptions are invisible to ELMAH, but not when elmah.mvc is in place.
MiniProfiler is a "simple but effective" profiler you can use to help find performance problems and bottlenecks. The project has come a long way over the last year. To get started with MiniProfiler, you can install the MiniProfiler.MVC3 package (which also works in ASP.NET MVC 4). After installation, add a single line of code to your _Layout view(s) before the closing </body> tag:
@StackExchange.Profiling.MiniProfiler.RenderIncludes()
Update:
You'll also need to add a handler so MiniProfiler can retrieve the scripts it needs:
<system.webServer>
...
<handlers>
<add name="MiniProfiler" path="mini-profiler-resources/*" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
Once everything is ready, you'll start to see the MiniProfiler results appear in the top left of the browser window (for local request only, by default). Click on the time measurement to see more details:

MiniProfiler can tell you how long it takes for actions to execute and views to render, and provides an API if you need to instrument specific pieces of code. The MiniProfiler install will also add a MiniProfiler.cs file in your App_Start directory. This file is where most of the MiniProfiler configuration takes place. From here you can enable authorization and database profiling.
Two great projects to check out, if you haven't seen them before.
The migrations feature of the Entity Framework includes a Seed method where you can populate the database with the initial static data an application needs. For example, a list of countries.
protected override void Seed(Movies.Infrastructure.MovieData context)
{
context.Countries.AddOrUpdate(c => c.Name,
new Country {Name = "India"},
new Country {Name = "Japan"},
// ..
);
}

protected override void Seed(CitationData context)
{
var resourceName = "Citations.App_Data.Countries.xml";
var assembly = Assembly.GetExecutingAssembly();
var stream = assembly.GetManifestResourceStream(resourceName);
var xml = XDocument.Load(stream);
var countries = xml.Element("Countries")
.Elements("Country")
.Select(x => new Country
{
Name = (string)x.Element("Name"),
}).ToArray();
context.Countries.AddOrUpdate(c=>c.Name, countries);
}
Jon Galloway has an overview of the new membership features in ASP.NET MVC 4. The Internet project template moves away from the core membership providers of ASP.NET and into the world of SimpleMembershipProvider and OAuth.
There is quite a bit I could write about the new features and the code generated by the Internet project template, but for this post I just want to cover a scenario I've demonstrated in the past - seeding the roles and membership tables. If you are using Entity Framework code-first migrations it's relatively easy to add some code to the Seed method of the migrations configuration to populate the membership tables with some initial roles and users. Just remember every update-database command will call the Seed method, so you have to write the code to make sure you don't try to create duplicate data.
First, the new project template creates an MVC 4 Internet application without any provider configuration, but for the membership features to work properly during a migration, it appears you need at least some configuration. The following code makes sure the SimpleMembershipProvider and SimpleRolesProvider are in place.
<roleManager enabled="true" defaultProvider="simple">
<providers>
<clear/>
<add name="simple" type="WebMatrix.WebData.SimpleRoleProvider,
WebMatrix.WebData"/>
</providers>
</roleManager>
<membership defaultProvider="simple">
<providers>
<clear/>
<add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider,
WebMatrix.WebData"/>
</providers>
</membership>
Then inside the Seed method of the DbMigrationsConfiguration<T> derived class, you can have:
protected override void Seed(MovieDb context)
{
//context.Movies.AddOrUpdate(...);
// ...
SeedMembership();
}
private void SeedMembership()
{
WebSecurity.InitializeDatabaseConnection("DefaultConnection",
"UserProfile", "UserId", "UserName", autoCreateTables: true);
var roles = (SimpleRoleProvider) Roles.Provider;
var membership = (SimpleMembershipProvider) Membership.Provider;
if (!roles.RoleExists("Admin"))
{
roles.CreateRole("Admin");
}
if (membership.GetUser("sallen",false) == null)
{
membership.CreateUserAndAccount("sallen", "imalittleteapot");
}
if (!roles.GetRolesForUser("sallen").Contains("Admin"))
{
roles.AddUsersToRoles(new[] {"sallen"}, new[] {"admin"});
}
}
Imagine you have the following types defined.
public class Movie
{
public int Id { get; set; }
public string Title { get; set; }
public MovieGenre Genre { get; set; }
}
public enum MovieGenre
{
Action,
Drama,
Adventure,
Fantasy,
Boring
}
If you want to display MovieGenre, the DisplayFor helpers generally give you what you expect (i.e. @Html.DisplayFor(m=> m.Genre) displays "Adventure"), but EditorFor will only give you a text input because the framework treats an enum the same as a string.

If the user knows your enum values they can type in a value and model binding works correctly, but we certainly don't want users to guess the valid values. A better approach would use a drop down list, or a set of radio buttons, to constrain and guide the user's input. There are a few articles on the web showing how to build a drop down list from enums (Stuart Leeks has a good one - Creating a DropDownList helper for enums). I wanted to try a slightly different approach using templates and supporting localization. If you are familiar with templates in ASP.NET MVC, see Brad Wilson's series on templates and metadata).
The first challenge is getting the MVC framework to select a custom template when it sees @Html.EditorFor(m => m.Genre). If you create a view named MovieGenre.cshtml and place it in the ~/Views/Shared/EditorTemplates folder, the MVC runtime will use the template and you can place inside the template any custom markup you want for editing a Genre. However, trying to have a single generic template (Enum.cshtml) for all enums won't work. The MVC framework sees the enum value as a simple primitive and uses the default string template. One solution to change the default framework behavior is to write a custom model metadata provider and implement GetMetadataForProperty to use a template with the name of "Enum" for such models.
public override ModelMetadata GetMetadataForProperty(
Func<object> modelAccessor, Type containerType, string propertyName)
{
var result = _inner.GetMetadataForProperty(modelAccessor, containerType, propertyName);
if (result.TemplateHint == null &&
typeof(Enum).IsAssignableFrom(result.ModelType))
{
result.TemplateHint = "Enum";
}
return result;
}
The "_inner" field represents the default metadata provider. Depending on how you want to setup the runtime, _inner could also be a call to the base class if you derive from CachedDataAnnotationsModelMetadataProvider. Regardless of the approach, the above code will rely on another provider to do the hard work. The code only throws in "Enum" as the template name to use if there is no template name specified and the model type derives from Enum.
With a custom metadata provider in place the runtime will locate and use an Enum template when a view uses EditorFor against a MovieGenre property.

The implementation of the template is straightforward. Regardless of the type of UI you want, you'll need to use Enum.GetValues to get all the possible values of the enumeration. You can then use the values to build a drop down list, radio buttons, anything you can image. The following code would render a simple drop down list.
@model Enum
@{
var values = Enum.GetValues(ViewData.ModelMetadata.ModelType).Cast<object>()
.Select(v => new SelectListItem
{
Selected = v.Equals(Model),
Text = v.ToString(),
Value = v.ToString()
});
}
@Html.DropDownList("", values)
Things get a little more complicated in the view if you want to customize the text display of an enum value, or if you want to localize the text using resource files. The Display attribute does most of the work, but as far as I can tell the code has to dig out the attribute on its own (there is no help from the MVC metadata provider). For example, take the following definition for MovieGenre.
public enum MovieGenre
{
[Display(ResourceType = typeof(Resources.Translations), Name = "Action")]
Action,
[Display(Name="Drama!")]
Drama,
Adventure,
Fantasy,
Boring
}
The following template code will display the proper text value, even localized, to the user.
@using System.ComponentModel.DataAnnotations
@model Enum
@{
Func<object, string> GetDisplayName = o =>
{
var result = null as string;
var display = o.GetType()
.GetMember(o.ToString()).First()
.GetCustomAttributes(false)
.OfType<DisplayAttribute>()
.LastOrDefault();
if (display != null)
{
result = display.GetName();
}
return result ?? o.ToString();
};
var values = Enum.GetValues(ViewData.ModelMetadata.ModelType).Cast<object>()
.Select(v => new SelectListItem
{
Selected = v.Equals(Model),
Text = GetDisplayName(v),
Value = v.ToString()
});
}
@Html.DropDownList("", values)
I'd want to measure the performance of the template if it is heavily used in a busy application, but the idea here is to use this approach if you want to create some fancy markup in the template. If all you want to do is ultimately call Html.DropDownList, a custom HTML helper approach is simpler.