由于.Net MVC 5登陆和注册方式有很多种,但是Identity方式去实现或许会更简单更容易理解
开发工具:Vs2017
数据库:Sql Server2012
代码下载:
链接:https://pan.baidu.com/s/1JXxMu36h0SmuxGkl2HwHrA
提取码:6g0u
1、首先新建一个项目
然后打开NuGet包管理器分别安装几个包
EntityFramework
Microsoft.AspNet.Identity.Core
Microsoft.AspNet.Identity.EntityFramework
Microsoft.AspNet.Identity.Owin
Modernizr
Microsoft.Owin.Host.SystemWeb
Bootstrap
2、往Models文件夹新增类:
public class ApplicationDbContext:IdentityDbContext<ApplicationUser> { public ApplicationDbContext() : base("IdentityDemo") { } public static ApplicationDbContext Cteate() { return new ApplicationDbContext(); } }
public class ApplicationUser:IdentityUser { }
public class SignInModel { [Required] [Display(Name ="Email")] public string Email { get; set; } [Required] [Display(Name = "Password")] [DataType(DataType.Password)] public string Password { get; set; } [Display(Name = "RememberMe")] public bool RememberMe { get; set; } }
public class SignUpModel { [Required] [Display(Name = "邮箱:")] public string Email { get; set; } [Required] [Display(Name = "密码:")] [DataType(DataType.Password)] public string Password { get; set; } [Required] [Display(Name = "确认密码:")] [DataType(DataType.Password)] [Compare("Password", ErrorMessage = "两次密码不一致!")] public string ConfirmPassword { get; set; } }
3、在App_Start文件夹下添加类
public class ApplicationSignInManager : SignInManager<ApplicationUser, string> { public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager) { } public static ApplicationSignInManager Cteate(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) { return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); } }
public class ApplicationUserManager:UserManager<ApplicationUser> { public ApplicationUserManager(IUserStore<ApplicationUser> store) : base(store) { } public static ApplicationUserManager Create( IdentityFactoryOptions<ApplicationUserManager> options ,IOwinContext context) { var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); return manager; } }
public class ApplicationUserStore:UserStore<ApplicationUser> { public ApplicationUserStore(ApplicationDbContext context) : base(context) { } }
4、创建控制器(然后往Controller文件夹里面添加HomeController控制器,AccountController控制器)
(1)先往HomeController控制器里添加index视图
index试图代码
@using Microsoft.AspNet.Identity @{ ViewBag.Title = "Index"; } <h2>Index</h2> @if (Request.IsAuthenticated) { using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" })) { @Html.AntiForgeryToken() <p>Hello @User.Identity.GetUserName()</p> <ul> <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li> </ul> } } else { <ul> <li> @Html.ActionLink("Login", "Login", "Account") </li> <li> @Html.ActionLink("Register", "Register", "Account") </li> </ul> }
(2)、然后AccountController控制器代码
public class AccountController : Controller { private ApplicationSignInManager _signInManager; private ApplicationUserManager _userManager; public AccountController() { } public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager) { UserManager = userManager; SignInManager = signInManager; } public ApplicationSignInManager SignInManager { get { return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); } private set { _signInManager = value; } } public ApplicationUserManager UserManager { get { return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); } private set { _userManager = value; } } [AllowAnonymous] public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(SignInModel model, string returnUrl) { if (!ModelState.IsValid) { return View(model); } var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.Failure: default: ModelState.AddModelError("", "登陆无效"); return View(model); } } [AllowAnonymous] public ActionResult Register() { return View(); } [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(SignUpModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; 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); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult LogOff() { AuthenticationManager.SignOut(); return RedirectToAction("Index", "Home"); } private void AddErrors(IdentityResult result) { foreach (var error in result.Errors) { ModelState.AddModelError("", error); } } private ActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } return RedirectToAction("Index", "Home"); } private IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } } }
然后分别添加生成Login和Register页面
Login页面代码
@model IdentityDemo.Models.SignInModel @{ ViewBag.Title = "Login"; } <h2>Login</h2> @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>SignInModel</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.TextBoxFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.PasswordFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.RememberMe, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> <div class="checkbox"> @Html.CheckBoxFor(model => model.RememberMe) @Html.ValidationMessageFor(model => model.RememberMe, "", new { @class = "text-danger" }) </div> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="SignIn" class="btn btn-default" /> </div> </div> </div> } <div> @Html.ActionLink("注册", "Register") </div>
Register页面代码
@model IdentityDemo.Models.SignUpModel @{ ViewBag.Title = "Register"; } <h2>Register</h2> @using (Html.BeginForm("Register", "Account", FormMethod.Post)) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>SignUpModel</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.TextBoxFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.TextBoxFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.TextBoxFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="SignUp" class="btn btn-default" /> </div> </div> </div> }
5、项目的根目录添加Startup类
public class Startup { public void Configuration(IAppBuilder app) { app.CreatePerOwinContext<ApplicationDbContext>(ApplicationDbContext.Cteate); app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Cteate); app.UseCookieAuthentication( new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new Microsoft.Owin.PathString("/Account/Login") }); } }
6、修改根目录的Web.Config文件
<?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=301880 --> <configuration> <connectionStrings> <add name="IdentityDemo" providerName="System.Data.SqlClient" connectionString="server=LocalHost;Database=SignTest;User Id=sa;Password=`12qwe;"/> </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" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.6.1" /> <httpRuntime targetFramework="4.6.1" /> </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.WebPages" 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.2.4.0" newVersion="5.2.4.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> <system.codedom> <compilers> <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" /> <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE="Web" /optionInfer+" /> </compilers> </system.codedom> <!--<entityFramework> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework>--> </configuration>
7、最后我们来测试一下看看效果怎么样,如下图