源码在这里:https://github.com/darrenji/UseIdentityCRUDUserInMVC,本地下载
在VS2013中创建一个MVC项目,用默认的"无身份验证"作为身份验证机制。
通过控制台下载Bootstrap。
- Install-Package -version 3.0.3 bootstrap
复制代码
下载成功后,在解决方案下的Content和Scripts多了该版本的css和js文件。
把创建项目默认HomeController中的所有Action以及/Views/Home下的所有视图删除。
热热身
先来做一个简单练习。
在HomeController中的Index方法中,把一个字典传递给视图。
- public class HomeController : Controller
- {
- public ActionResult Index()
- {
- Dictionary<string, object> data = new Dictionary<string, object>();
- data.Add("placeholder", "placeholder");
- return View(data);
- }
- }
复制代码
_Layout.cshtml设置如下:
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>ASP.NET Identity实战</title>
- <link href="~/Content/bootstrap.min.css" rel="external nofollow" rel="stylesheet" />
- <link href="~/Content/bootstrap-theme.min.css" rel="external nofollow" rel="stylesheet" />
- <style>
- .container {padding-top:10px;}
- .validation-summary-errors{color:red;}
- </style>
- </head>
- <body>
-
- <div class="container">
- @RenderBody()
- </div>
- @Scripts.Render("~/bundles/jquery")
- @Scripts.Render("~/bundles/bootstrap")
- @RenderSection("scripts", required: false)
- </body>
复制代码
Home/Index.cshtml视图中:
- @{
- ViewBag.Title = "Index";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- <div class="panel panel-primary">
- <div class="panel-heading">用户明细</div>
- <table class="table table-striped">
- @foreach (string key in Model.Keys)
- {
- <tr>
- <th>@key</th>
- <td>@Model[key]</td>
- </tr>
- }
- </table>
- </div>
复制代码
前期准备
分别安装如下组件。
- Install-Package Microsoft.AspNet.Identity.EntityFramework –Version 2.0.0Install-Package Microsoft.AspNet.Identity.OWIN -Version 2.0.0Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0
复制代码
配置Web.config如下:
- <?xml version="1.0" encoding="utf-8"?>
- <!--
- 有关如何配置 ASP.NET 应用程序的详细信息,请访问
- http://go.microsoft.com/fwlink/?LinkId=301880
- -->
- <configuration>
- <configSections>
- <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
- <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
- </configSections>
- <connectionStrings>
- <add name="IdentityDb" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)\v11.0;Initial Catalog=IdentityDb;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;MultipleActiveResultSets=True"/>
- </connectionStrings>
- <appSettings>
- <add key="webpages:Version" value="3.0.0.0" />
- <add key="webpages:Enabled" value="false" />
- <add key="ClientValidationEnabled" value="true" />
- <add key="UnobtrusiveJavaScriptEnabled" value="true" />
- <add key="owin:AppStartup" value="WebApplication4.IdentityConfig" />
- </appSettings>
- <system.web>
- <compilation debug="true" targetFramework="4.5" />
- <httpRuntime targetFramework="4.5" />
- </system.web>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
- <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
- <bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
- <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
- <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
- </dependentAssembly>
- <dependentAssembly>
- <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
- <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
- <entityFramework>
- <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
- <providers>
- <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
- </providers>
- </entityFramework>
- </configuration>
复制代码
以上,
- 增加了connectionStrings节点,将自动创建localdb数据库
- 在appSettings节点中增加了一个key为owin:AppStartup项,这是确保OWIN运行正常的全局配置
在Models文件夹下创建如下类。
- public class AppUser : IdentityUser
- {
- }
复制代码
在解决方案下创建Infrastructure文件夹。
在Infrastructure文件夹下创建一个上下文类,需要实现IdentityDbContext<>接口。
- public class AppIdentityDbContext : IdentityDbContext<AppUser>
- {
- public AppIdentityDbContext()
- : base("IdentityDb")
- {
- }
- static AppIdentityDbContext()
- {
- //使用EF Code First第一次创建的时候调用
- Database.SetInitializer<AppIdentityDbContext>(new IdentityDbInit());
- }
- public static AppIdentityDbContext Create()
- {
- return new AppIdentityDbContext();
- }
- }
- //初始化
- public class IdentityDbInit : DropCreateDatabaseIfModelChanges<AppIdentityDbContext>
- {
- protected override void Seed(AppIdentityDbContext context)
- {
- PerformInitialSetup(context);
- base.Seed(context);
- }
- //初始化工作
- public void PerformInitialSetup(AppIdentityDbContext context)
- { }
- }
复制代码
在Infrastructure文件夹下创建一个管理用户的类,需要继承UserManager类。
还记得,先前在appSettings节点中配置了一个如下方式:
- <add key="owin:AppStartup" value="WebApplication4.IdentityConfig" />
复制代码
OWIN需要一个全局启动文件,默认会到项目的顶级命名空间下找IdentityConfig这个类。
那就在App_Start中创建IdentityConfig这个类,这个类在WebApplication4这个命名空间下。
- namespace WebApplication4
- {
- public class IdentityConfig
- {
- public void Configuration(IAppBuilder app)
- {
- app.CreatePerOwinContext<AppIdentityDbContext>(AppIdentityDbContext.Create);
- app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);
- app.UseCookieAuthentication(new CookieAuthenticationOptions {
- AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
- LoginPath = new Microsoft.Owin.PathString("/Account/Login")
- });
- }
- }
- }
复制代码
显示用户
创建AdminController,现在可以向视图传递所有的用户了,编写如下:
- public class AdminController : Controller
- {
- public ActionResult Index()
- {
- return View(UserManager.Users);
- }
- private AppUserManager UserManager
- {
- get
- {
- return HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
- }
- }
- }
复制代码
再创建Admin/Index.cshtml类型为IEnumerable的强类型视图。
- @model IEnumerable<WebApplication4.Models.AppUser>
- @{
- ViewBag.Title = "Index";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- <div class="panel panel-primary">
- <div class="panel-heading">
- 所有用户账户
- </div>
- <table class="table table-striped">
- <tr><th>ID</th><th>Name</th><th>Email</th><th></th></tr>
- @if (Model.Count() == 0)
- {
- <tr><td colspan="4" class="text-center">还没有创建用户</td></tr>
- }
- else
- {
- foreach (WebApplication4.Models.AppUser user in Model)
- {
- <tr>
- <td>@user.Id</td>
- <td>@user.UserName</td>
- <td>@user.Email</td>
- <td>
- @using (Html.BeginForm("Delete", "Admin",
- new { id = user.Id }))
- {
- @Html.ActionLink("编辑", "Edit", new { id = user.Id },
- new { @class = "btn btn-primary btn-xs" })
- <button class="btn btn-danger btn-xs"
- type="submit">
- 删除
- </button>
- }
- </td>
- </tr>
- }
- }
- </table>
- </div>
- @Html.ActionLink("创建用户", "Create", null, new { @class = "btn btn-primary" })
复制代码
创建用户
在Models文件夹下创建一个视图模型。
- namespace WebApplication4.Models
- {
- public class CreateModel
- {
- public string Id { get; set; }
- [Required]
- public string Name { get; set; }
- [Required]
- public string Email { get; set; }
- [Required]
- public string Password { get; set; }
- }
- }
复制代码
在AdminController中添加创建用户相关的方法。
- public class AdminController : Controller
- {
- public ActionResult Index()
- {
- return View(UserManager.Users);
- }
- //创建显示
- public ActionResult Create()
- {
- return View();
- }
- [HttpPost]
- public async Task<ActionResult> Create(CreateModel model)
- {
- if(ModelState.IsValid)
- {
- var user = new AppUser{UserName = model.Name, Email = model.Email};
- IdentityResult result = await UserManager.CreateAsync(user, model.Password);
- if(result.Succeeded)
- {
- return RedirectToAction("Index");
- }else{
- AddErrorsFromResult(result);
- }
- }
- return View(model);
- }
- //创建接收
- private void AddErrorsFromResult(IdentityResult result)
- {
- foreach(var error in result.Errors)
- {
- ModelState.AddModelError("", error);
- }
- }
- private AppUserManager UserManager
- {
- get
- {
- return HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
- }
- }
- }
复制代码
在Admin/Create.cshtml视图页中:
- @model WebApplication4.Models.CreateModel
- @{
- ViewBag.Title = "Create";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- <h2>Create</h2>
- @using (Html.BeginForm())
- {
- @Html.AntiForgeryToken()
-
- <div class="form-horizontal">
- <h4>创建用户</h4>
- <hr />
- @Html.ValidationSummary(true)
- <div class="form-group">
- @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
- <div class="col-md-10">
- @Html.EditorFor(model => model.Name)
- @Html.ValidationMessageFor(model => model.Name)
- </div>
- </div>
- <div class="form-group">
- @Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" })
- <div class="col-md-10">
- @Html.EditorFor(model => model.Email)
- @Html.ValidationMessageFor(model => model.Email)
- </div>
- </div>
- <div class="form-group">
- @Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" })
- <div class="col-md-10">
- @Html.EditorFor(model => model.Password)
- @Html.ValidationMessageFor(model => model.Password)
- </div>
- </div>
- <div class="form-group">
- <div class="col-md-offset-2 col-md-10">
- <input type="submit" value="创建用户" class="btn btn-default" />
- </div>
- </div>
- </div>
- }
- <div>
- @Html.ActionLink("返回", "Index")
- </div>
复制代码
点击"创建"按钮,创建成功返回显示用户页面。
oh, my god,只是配置了一下就有数据了? 数据在哪呢?
点击左上角的"服务器资源管理器",右键"IdentityDb",点击"刷新"。
再打开AspNetUsers表,刚创建的用户赫然在列。
好像还有点欠缺,用户输入密码的时候,总应该有些限制吧。
能想到的,ASP.NET Identity都为我们准备好了。有一个PasswordValidator类就是干这个的。
在Infrastructure文件夹中创建一个PasswordValidator类的继承子类。
- namespace WebApplication4.Infrastructure
- {
- public class CustomPasswordValidator : PasswordValidator
- {
- public override async Task<IdentityResult> ValidateAsync(string pass)
- {
- IdentityResult result = await base.ValidateAsync(pass);
- if (pass.Contains("12345"))
- {
- var errors = result.Errors.ToList();
- errors.Add("密码中包含太多连续数字");
- result = new IdentityResult(errors);
- }
- return result;
- }
- }
- }
复制代码
然后需要把这个规则告诉UserManager。
- namespace WebApplication4.Infrastructure
- {
- public class AppUserManager : UserManager<AppUser>
- {
- public AppUserManager(IUserStore<AppUser> store) : base(store) { }
- public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
- {
- //identity ef上下文
- AppIdentityDbContext db = context.Get<AppIdentityDbContext>();
- //与identity ef相关的UserStore
- IUserStore<AppUser> us = new UserStore<AppUser>(db);
- AppUserManager manager = new AppUserManager(us);
- //密码相关
- manager.PasswordValidator = new CustomPasswordValidator {
- RequiredLength = 6,
- RequireNonLetterOrDigit = false,
- RequireDigit = false,
- RequireLowercase = true,
- RequireUppercase = true
- };
- return manager;
- }
- }
- }
复制代码
再次运行程序,创建用户页面,尝试输入不通过的密码。
不过,关于密码的规则,似乎可以在View Model的验证层面就可以解决掉。
编辑和删除用户
在AdminController中增加编辑和删除的部分。
Admin/Edit.cshtml视图。
- @model WebApplication4.Models.CreateModel
- @{
- ViewBag.Title = "Edit";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- <h2>Edit</h2>
- @using (Html.BeginForm())
- {
- @Html.AntiForgeryToken()
-
- <div class="form-horizontal">
- <hr />
- @Html.ValidationSummary(true)
- @Html.HiddenFor(model => model.Id)
- <div class="form-group">
- @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
- <div class="col-md-10">
- @Html.EditorFor(model => model.Name)
- @Html.ValidationMessageFor(model => model.Name)
- </div>
- </div>
- <div class="form-group">
- @Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" })
- <div class="col-md-10">
- @Html.EditorFor(model => model.Email)
- @Html.ValidationMessageFor(model => model.Email)
- </div>
- </div>
- <div class="form-group">
- @Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" })
- <div class="col-md-10">
- @Html.EditorFor(model => model.Password)
- @Html.ValidationMessageFor(model => model.Password)
- </div>
- </div>
- <div class="form-group">
- <div class="col-md-offset-2 col-md-10">
- <input type="submit" value="保存" class="btn btn-default" />
- </div>
- </div>
- </div>
- }
- <div>
- @Html.ActionLink("返回", "Index")
- </div>
复制代码
另外,如果删除失败,跳转到Shared/Error.cshtml视图页。
- @model IEnumerable<string>
- @{ ViewBag.Title = "Error";}
- <div class="alert alert-danger">
- @switch (Model.Count())
- {
- case 0:
- @: Something went wrong. Please try again
- break;
- case 1:
- @Model.First();
- break;
- default:
- @: 发现如下错误:
- <ul>
- @foreach (string error in Model)
- {
- <li>@error</li>
- }
- </ul>
- break;
- }
- </div>
- @Html.ActionLink("确定", "Index", null, new { @class = "btn btn-default" })
复制代码
至此,使用ASP.NET Identy实现对用户的增删改查完毕,ASP.NET Identity真的很好很强大!
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对晓枫资讯的支持。如果你想了解更多相关内容请查看下面相关链接
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!