在 AspNet Identity 2.0 中显示用户全名,而不是用户电子邮件






4.54/5 (8投票s)
如何在 AspNet Identity 2.0 中用全名替换 User.Identity.Name(电子邮件)
引言
默认情况下,AspNet Identity 2.0 与 MVC 5 在 _LoginPartial.cshtml 页面中显示用户名,即用户的电子邮件地址。我将介绍如何将其更改为用户的 FirstName 和 LastName,即全名。
背景
AspNet Identity 2.0 使用用户电子邮件地址作为用户名,并在成功登录后显示它,通过显示部分视图 _LoginPartial 来确认用户。默认情况下,AspNet Identity 2.0 不存储用户的信息,例如名字或姓氏。要存储和使用用户的 First Name(名字)和 Last Name(姓氏),我们可以向 AspNetUsers 表添加新的列,或者添加新的表来存储它们,并通过 AspNetUsers 表进行链接。我将遵循第一种方法,即创建两个名为 FirstName 和 LastName 的列,并在成功登录后使用它们来显示完整的用户名。
描述
首先,我将使用 Visual Studio 2013 创建一个新的 MVC 5 ASP.NET Web 应用程序。
从可用模板列表中,我将选择 MVC 并单击 OK(确定)以创建项目。
创建项目后,它在 Solution Explorer(解决方案资源管理器)中的显示如下所示
在对项目进行任何更改之前,我将更新数据库连接字符串以指向我的 LocalDb 数据库,并将数据库名称更改为 AspNetIdentity2。
<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=AspNetIdentity2;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>
正如我所提到的,我将在用户注册应用程序时,向用户记录添加两个列 FirstName 和 LastName。
目前,默认的注册表单没有名字或姓氏字段。
要添加这两个新字段,我们需要确保模型数据验证这两个新字段,并且在用户注册时将它们正确插入到数据库中。
添加两个新的属性
我已将 FirstName 和 LastName 属性添加到 IdentityModels 中的 ApplicationUser 类中,如下所示
public class ApplicationUser : IdentityUser { public string FirstName { get; set; } public string LastName { get; set; } public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here return userIdentity; } }
我还将相同的两个属性添加到 AccountViewModels 中的 RegisterViewModel 类中,如下所示
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; } }
之后,我向 Registration(注册)视图添加了两个新的文本字段,以捕获用户的 FirstName(名字)和 LastName(姓氏)
@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> }
完成这些操作后,我们可以看到 Register(注册)视图中的两个新字段,如下所示
更新控制器方法
我将更新 Account(帐户)控制器中的 POST 方法,其中信息被保存到数据库。在这里,我添加了 FirstName 和 LastName 以与 Email(电子邮件)和 Password(密码)一起保存。
// POST: /Account/Register [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); // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 // Send an email with this link // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>"); return RedirectToAction("Index", "Home"); } AddErrors(result); } // If we got this far, something failed, redisplay form return View(model); }
在我们运行并注册应用程序之前,让我们使用两个列的更改来迁移数据库。
我已从 Package Manager Console(包管理器控制台)运行了该命令
Enable-Migrations
之后,我运行了该命令
Add-Migration
最后,为了更新数据库,我发布了
Update-Database
如果我们查看 AspNetUsers 表,我们可以看到两个新的列,它们在原始表中不存在,如右侧所示。
让我们运行并注册一个用户到应用程序
成功注册后,主页显示如下
更新代码以将用户的全名发送到视图
现在我将进行更改,以显示用户的全名,而不是电子邮件地址。
我将创建一个控制器类,它将成为应用程序其他控制器的基类。
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() { } } }
我已将所有控制器方法更改为继承 ApplicationBaseController,而不是 Controller。
例如,HomeController 继承 ApplicationBaseController,如下所示
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(); } } }
现在我已经更改了 _LoginPartial.cshtml,如下所示,以从 ViewData 显示用户的全名,因为 ApplicationBaseController 发送了全名。
@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>
}
现在我们可以看到显示了全名。
关注点
AspNet Identity 2.0, MVC 5