Introduction
AspNet Identity 2.0 with MVC 5 by default displays the username which is user's email address in _LoginPartial.cshtml page. I will go through how to change this to user's FirstName and LastName i.e. Full Name
Background
AspNet Indentity 2.0 uses user email address as user name and displays it on successfull login to confirm the user by showing the partial view _LoginPartial. As default AspNet Identity 2.0 does not store user information such as first name or last name. To store and use user's First Name and Last Name, we can create new columns to the AspNetUsers table or add new table to store them by linking with the AspNetUsers table. I will follow the first approach where I will create two columns named as FirstName and LastName and use them to display the full user name after successful login.
Description
To start with I am going to create a new MVC 5 ASP.NET Web application in using Visual Studio 2013.
From the list of available templates I will choose MVC and click OK to create the project.
When the project is created, it looks as below in the Solution Explorer:
Before doing any change to the project, I will update the database connection string to point to my LocalDb database and change the database name to AspNetIdentity2.
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=AspNetIdentity2;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>Colourised in 3ms
As I mentioned I will add two columns FirstName and LastName to the user record while registering the user to the application.
Currently the default registration form does not have First Name or Last Name fields.
To add the new two fields we need to make sure that the model data validates the two new fields and they are correctly inserted to the database while the user does the registtraion.
Adding two new properties
I have added FirstName and LastName properties to the IdentityModels in ApplicationUser class as below:
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
Colourised in 10ms
I have also added the same two properties to the RegisterViewModel class in AccountViewModels as below:
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
Colourised in 23ms
After that I have added two new text fields to the Registration view to capture user's FirstName and Last Name
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Create a new account.</h4>
<hr />
@Html.ValidationSummary("", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.FirstName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.FirstName, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.LastName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.LastName, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Register" />
</div>
</div>
}Colourised in 27ms
Having done these, we can see the two new fields in the Register view as below:
Updating controller methods
I will update the POST method in Account controller where the information are saved to the database. Here I have added FirstName and LastName to save with Email and Password.
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
FirstName = model.FirstName,
LastName = model.LastName
};
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
return View(model);
}
Colourised in 35ms
Before we run and register for the application, let us migrate the database with the changes for to columns.
I have run the command from the Package Manager Console
Enable-MigrationsColourised in 0ms
After that I run the command
Add-MigrationColourised in 0ms
And finally to update the database I issued
Update-DatabaseColourised in 0ms
If we look at AspNetUsers table we can see two new columns which are not present in the original table as shown on the right side.
Let us run and register a user to the application
After successful registration the Home page looks as below:
Updating code to send users' full name to the view
Now I will make changes for displaying the user's Full Name instead of the email address.
I will create a Controller class that will be the base controller for other controllers for the application.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AspNetIdentity2.Models;
namespace AspNetIdentity2.Controllers
{
public class ApplicationBaseController : Controller
{
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (User != null)
{
var context = new ApplicationDbContext();
var username = User.Identity.Name;
if (!string.IsNullOrEmpty(username))
{
var user = context.Users.SingleOrDefault(u => u.UserName == username);
string fullName = string.Concat(new string[] { user.FirstName, " ", user.LastName });
ViewData.Add("FullName", fullName);
}
}
base.OnActionExecuted(filterContext);
}
public ApplicationBaseController()
{ }
}
}Colourised in 22ms
I have changed all controller methods to inherit the ApplicationBaseController instead of Controller.
For instance the HomeController inherits ApplicationBaseController as below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace AspNetIdentity2.Controllers
{
public class HomeController : ApplicationBaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}Colourised in 15ms
Now I have changed the _LoginPartial.cshtml as below to display the user's Full Name from ViewData as the ApplicationBaseController sends the full name.
@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated && ViewData.ContainsKey("FullName"))
{
using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<ul class="nav navbar-nav navbar-right">
<li>
@Html.ActionLink("Hello " + (ViewData["FullName"]) + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
</li>
<li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
</ul>
}
}
else
{
<ul class="nav navbar-nav navbar-right">
<li>@Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink" })</li>
<li>@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li>
</ul>
}Colourised in 10ms
Now we can see the full name is displayed.
Points of Interest
AspNet Identity 2.0, MVC 5