- Introduction
- Simulation
- Domain Model
- Server Data Services
- Web API Crud
- U.I. Mockup
I started the LobGame Gamification Service Administration website by using the MVC 4 Internet template. The last blog post in this series shared a mocked up version of the user interface where the first screen in the workflow requires the user to sign in or register.
In this blog post, I would like to discuss the authentication process provided by the MVC 4 Internet template. There are 2 fantastic posts you should read first.
- MVC 4 Authentication
- SimpleMembership, Membership Providers, Universal Providers and the new ASP.NET 4.5 Web Forms and ASP.NET MVC 4 templates
In addition, please check out Scott Allen’s excellent Pluralsight course called "Building Applications with ASP.NET MVC 4".
I would like to demonstrate modifying the MVC 4 Internet Template to work with a custom domain model/database with its own custom "user
" table. The completed code can be found here.
MVC 4 Internet Template with Pre-existing Domain Model
Create a new ASP.NET MVC 4 Internet Application and name it "SimpleMemberExample
".
Custom Domain Model/Database
The first thing I want to do is create the custom domain model/database. In the "Model" directory, let's add a class that represents our custom "User
" table. Let's call this custom user entity "Administrator
" as seen here:
namespace SimpleMembershipExample.Models
{
public class Administrator
{
public Administrator(){}
#region Fields and Properties
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
#endregion
}
}
Let's add a custom DbContext
as shown here to the root of the project.
using System.Data.Entity;
using SimpleMembershipExample.Models;
namespace SimpleMembershipExample
{
public class SomeAppDbContext: DbContext
{
public SomeAppDbContext(): base(nameOrConnectionString: "SomeAppName"){}
public DbSet<Administrator> Administrators { get; set; }
}
}
The DbContext
only contains a single table called Administrators
just to keep this super duper easy. Yours would contain lots more. Notice in the custom constructor, I am telling the DbContext
to use a specific connection string. Let's add that connection string to the Web.Config.
This connection string could be anything you want it to be.
Just for demo purposes, I am naming the database "SomeAppName
". As a final step, in "Global.asax.cs", put the following code:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
SomeAppDbContext dbcontext = new SomeAppDbContext();
dbcontext.Administrators.All(i => i.Name != "Dan");
Running the application, the magical EF Code First will create the following database. We have a custom database with a custom user table called "Administrators
".
Customizing MVC 4 Internet Template
Remove InitializeSimpleMembershipAttribute
The Internet template contains an Action
filter called "InitializeSimpleMembershipAttribute
". I deleted that class and removed any references to it.
Replace UserProfile with your Custom User Entity
The Internet template assumes that it will be adding a user table called "UserProfile
" to your database. What I think a high percentage of developers would want is to use their domain model’s "user" entity and have SimpleMembership
just manage the passwords. Let me demonstrate how to do this.
In the "Model" folder, in the "AccountModel.cs" file, delete the "UserProfile
" class. We want to use our "Administrator
" entity instead. Wherever UserProfile
is referenced elsewhere, replace with Administrator. The original UserProfile
had properties called "UserName
" and "UserId
". Administrator
has properties "Name
" and "Id
". Make sure to sync those properties up.
I want to have only 1 DbContext
and I want to use my DbContext
. In the "Model" folder, in the "AccountModel.cs" file, delete the "UsersContext
" class. Wherever UsersContext
is referenced elsewhere, replace with SomeAppDbContext
.
Call WebSecurity.InitializeDatabaseConnection
As a final step, in "Global.asax.cs", put the following code:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
SomeAppDbContext dbcontext = new SomeAppDbContext();
dbcontext.Administrators.All(i => i.Name != "Dan");
WebSecurity.InitializeDatabaseConnection("SomeAppName",
"Administrators", "Id", "Name", autoCreateTables: true);
WebSecurity.InitializeDatabaseConnection
takes the web.config connection string name, the name of your custom user table ("Administrators
"), the unique identifier field name of your user table ("Id
") and the user name field. Running the InitializeDatabaseConnection
method does several things:
- Initializes the static
Roles
and WebSecurity
classes. - Adds the following tables to your database:
webpages_Membership, webpages_OAuthMembership
, webpages_Roles
, webpages_UsersInRoles
, UserProfile
.
Running the Internet Application
When you run the code with those changes, the following database is created:
The home screen looks like this:
Click on the Register link in the upper right.
Fill out the form and click the "Register" button. The MVC 4 Internet template application will navigate you back to the home page.
Notice it knows the name you registered with. If you check for cookies, you will see the typical ASPXAUTH
as shown below:
If you click the "Log off" link and check cookies, the ASPXAUTH
cookie disappears. The ASPXAUTH
cookie is the key to the authentication.
When you look at the database, you will see the following:
Notice with the code changes, the MVC Internet template knew to save to the custom user table "Administrators
". The password was saved to the webpages_Membership
table with a foreign key relationship to the Administrators
table.
Please download the code here.
LobGame Gamification Authentication
If you look at previous posts in the series, the Administrator
entity looked like this:
using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
namespace LobGame.Model
{
public class Administrator
{
public Administrator()
{
Applications = new List<Application>();
}
#region Fields and Properties
public Guid Id { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public List<Application> Applications { get; set; }
#endregion
}
}
Notice the Id
was a Guid
. I was unable to figure out how to keep the data type as a Guid
. I think the unique identifier of your custom user entity/table must be an int
to use SimpleMembership
.
Also notice I had "Password
" as a field. I removed this as it is no longer needed. The new Administrator
class looks like this:
using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
namespace LobGame.Model
{
public class Administrator
{
public Administrator()
{
Applications = new List<Application>();
}
#region Fields and Properties
public int Id { get; set; }
public string Name { get; set; }
public string Mobile { get; set; }
public List<Application> Applications { get; set; }
#endregion
}
}
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.