65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.54/5 (8投票s)

2015年5月15日

CPOL

3分钟阅读

viewsIcon

106594

如何在 AspNet Identity 2.0 中用全名替换 User.Identity.Name(电子邮件)

引言

默认情况下,AspNet Identity 2.0MVC 5_LoginPartial.cshtml 页面中显示用户名,即用户的电子邮件地址。我将介绍如何将其更改为用户的 FirstName 和 LastName,即全名。

背景

AspNet Identity 2.0 使用用户电子邮件地址作为用户名,并在成功登录后显示它,通过显示部分视图 _LoginPartial 来确认用户。默认情况下,AspNet Identity 2.0 不存储用户的信息,例如名字或姓氏。要存储和使用用户的 First Name(名字)和 Last Name(姓氏),我们可以向 AspNetUsers 表添加新的列,或者添加新的表来存储它们,并通过 AspNetUsers 表进行链接。我将遵循第一种方法,即创建两个名为 FirstNameLastName 的列,并在成功登录后使用它们来显示完整的用户名。

描述

首先,我将使用 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>

正如我所提到的,我将在用户注册应用程序时,向用户记录添加两个列 FirstNameLastName

目前,默认的注册表单没有名字或姓氏字段。

要添加这两个新字段,我们需要确保模型数据验证这两个新字段,并且在用户注册时将它们正确插入到数据库中。

添加两个新的属性

我已将 FirstNameLastName 属性添加到 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 方法,其中信息被保存到数据库。在这里,我添加了 FirstNameLastName 以与 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

© . All rights reserved.