如何一步步构建以长尾词为核心的MVC电商网站BooksStore?

2026-04-01 09:271阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2791个文字,预计阅读时间需要12分钟。

如何一步步构建以长尾词为核心的MVC电商网站BooksStore?

逐步构建一个简单的MVC电子商务网站 - BooksStore(四)系列GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore《一步步构建一个简单的MVC电子商务网站 - BooksStore(一)》《一步步构建一个简单的MVC电子商务网站 - BooksStore(二)》《一步步构建一个简单的MVC电子商务网站 - BooksStore(三)》

一步步打造一个简单的 MVC 电商网站 - BooksStore(四)

本系列的 GitHub地址:github.com/liqingwen2015/Wen.BooksStore

《一步步打造一个简单的 MVC 电商网站 - BooksStore(一)》

《一步步打造一个简单的 MVC 电商网站 - BooksStore(二)》

《一步步打造一个简单的 MVC 电商网站 - BooksStore(三)》

《一步步打造一个简单的 MVC 电商网站 - BooksStore(四)》

简介

  上一节我们完成了两个主要功能:完成了整个购物车的流程,以及订单处理(发邮件进行通知),今天我们来学习一下最基本的增删改查,以及登录认证过滤器,加入防 CSRF 攻击,本系列已完结。

  该系列主要功能与知识点如下:

  分类、产品浏览、购物车、结算、CRUD(增删改查) 管理、发邮件、分页、模型绑定、认证过滤器和单元测试等。

项目使用 VS2015 + C#6 进行开发,有问题请发表在留言区哦,还有,页面长得比较丑,请见谅。

目录

基本的增删改查 CRUD

登录授权认证过滤

基本的增删改查 CRUD

我们创建一个新的控制器进行增删改查功能,AdminController,并添加一个显示所有数据的方法:

/// <summary> /// 后台管理控制器 /// </summary> public class AdminController : Controller { private readonly IBookRepository _bookRepository; public AdminController(IBookRepository bookRepository) { _bookRepository = bookRepository; } /// <summary> /// 首页 /// </summary> /// <returns></returns> public ActionResult Index() { return View(_bookRepository.Books); } }

不在沿用之前的布局页了,创建一个新的布局页 _AdmindLayout.cshtml:

<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> <link href="~/Contents/admin/Site.css" rel="stylesheet" /> </head> <body> <div> @RenderBody() </div> </body> </html>

Site.css

.table { width: 100%; padding: 0; margin: 0; } .table th { font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; color: #4f6b72; border-right: 1px solid #C1DAD7; border-bottom: 1px solid #C1DAD7; border-top: 1px solid #C1DAD7; letter-spacing: 2px; text-transform: uppercase; text-align: left; padding: 6px 6px 6px 12px; background: #CAE8EA no-repeat; } .table td { border-right: 1px solid #C1DAD7; border-bottom: 1px solid #C1DAD7; background: #fff; font-size: 14px; padding: 6px 6px 6px 12px; color: #4f6b72; } .table td.alt { background: #F5FAFA; color: #797268; } .table th.spec, td.spec { border-left: 1px solid #C1DAD7; }

对应的Index.cshtml:

@model IEnumerable<Wen.BooksStore.Domain.Entities.Book> @{ Layout = "~/Views/Shared/_AdminLayout.cshtml"; } <p> @Html.ActionLink("新增", "Edit") </p> <table class="table"> <tr> <th> 名称 </th> <th> 描述 </th> <th> 价格 </th> <th> 分类 </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Description) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.DisplayFor(modelItem => item.Category) </td> <td> @Html.ActionLink("编辑", "Edit", new { id = item.Id }) @using (Html.BeginForm("Delete", "Admin", FormMethod.Post, new { style = "display:inline;" })) { @Html.Hidden("id", item.Id) <input type="submit" value="删除" /> } </td> </tr> } </table>

编辑,我把新增和编辑的位置放在一块,使用 id 进行区分,如果 id = 0 就表示新增的信息。

在 AdminCtroller 中添加关于编辑的方法

/// <summary> /// 编辑 /// </summary> /// <param name="id"></param> /// <returns></returns> public ActionResult Edit(int id = 0) { if (id == 0) { return View(new Book()); } var model = _bookRepository.Books.FirstOrDefault(x => x.Id == id); return View(model); } /// <summary> /// 编辑 /// </summary> /// <param name="book"></param> /// <returns></returns> [HttpPost] public ActionResult Edit(Book book) { if (!ModelState.IsValid) { return View(book); } _bookRepository.SaveBook(book); return RedirectToAction("Index"); }

更新存储库中的方法:

IBookRepository.cs

/// <summary> /// 书存储库接口 /// </summary> public interface IBookRepository { /// <summary> /// 书模型集合 /// </summary> IQueryable<Book> Books { get; } /// <summary> /// 保存书 /// </summary> /// <param name="book"></param> /// <returns></returns> int SaveBook(Book book); /// <summary> /// 删除书 /// </summary> /// <param name="id"></param> /// <returns></returns> Book DeleteBook(int id); }

EfBookRepository.cs

/// <summary> /// 书存储库 /// </summary> public class EfBookRepository : IBookRepository { private readonly EfDbContext _context = new EfDbContext(); /// <summary> /// 书模型集合 /// </summary> public IQueryable<Book> Books => _context.Books; /// <summary> /// 保存书 /// </summary> /// <param name="book"></param> /// <returns></returns> public int SaveBook(Book book) { if (book.Id == 0) { _context.Books.Add(book); } else { var model = _context.Books.Find(book.Id); if (model==null) { return 0; } model.Category = book.Category; model.Description = book.Description; model.Name = book.Name; model.Price = book.Price; } return _context.SaveChanges(); } /// <summary> /// 删除书 /// </summary> /// <param name="id"></param> /// <returns></returns> public Book DeleteBook(int id) { var model = _context.Books.Find(id); if (model == null) { return null; } _context.Books.Remove(model); _context.SaveChanges(); return model; } }

需要对 Book 模型加上验证用的特性:

[Table("Book")] public class Book { /// <summary> /// 标识 /// </summary> public int Id { get; set; } /// <summary> /// 名称 /// </summary> [Required(ErrorMessage = "名称不能为空")] public string Name { get; set; } /// <summary> /// 描述 /// </summary> [Required(ErrorMessage = "描述不能为空")] public string Description { get; set; } /// <summary> /// 价格 /// </summary> [Required(ErrorMessage = "价格不能为空")] [Range(0.01, double.MaxValue, ErrorMessage = "请填写合适的价格")] public decimal Price { get; set; } /// <summary> /// 分类 /// </summary> [Required(ErrorMessage = "分类不能为空")] public string Category { get; set; } }

_AdminLayout.cshtml 需要引入验证用的 js(客户端验证):

如何一步步构建以长尾词为核心的MVC电商网站BooksStore?

<script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/jquery.validate.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

Edit.cshtml

@model Wen.BooksStore.Domain.Entities.Book @{ Layout = "~/Views/Shared/_AdminLayout.cshtml"; } <h2>编辑</h2> <div> @Html.ValidationSummary() <div> @using (Html.BeginForm()) { @Html.HiddenFor(x => x.Id) <table> <tr> <td>名称</td> <td>@Html.TextBoxFor(x => x.Name)</td> </tr> <tr> <td>价格</td> <td>@Html.TextBoxFor(x => x.Price)</td> </tr> <tr> <td>分类</td> <td>@Html.TextBoxFor(x => x.Category)</td> </tr> <tr> <td>描述</td> <td>@Html.TextAreaFor(x => x.Description)</td> </tr> </table> <input type="submit" value="提交" /> } </div> </div>

图:错误提示

删除

/// <summary> /// 删除 /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpPost] public ActionResult Delete(int id) { _bookRepository.DeleteBook(id); return RedirectToAction("Index"); }

加入提示,我们在新增、编辑和删除时应该加入必要的提示信息,使用TempData。

/Admin/Index.cshtml 下的也要添加:

执行效果:

TempData 临时数据保存了一条信息,是一个“键/值”字典,类似会话 Session 和 ViewBag,它和 Session 的差别是,在 HTTP 请求结束后会被删除。因为这里使用了 RedirectToAction ,一条重定向指令,会告诉浏览器重定向请求到一个新地址,这时就不能使用 ViewBag,ViewBag 用于在控制器与视图之间传递数据,但它保持数据的时间不能比当前的HTTP 请求长,重定向意味着用户是跨请求的,ViewBag 不能用于跨请求时传递数据。

登录授权认证过滤

上面是一个 Admin 的后台管理操作,不是每一个用户都能够进入管理的,所以现在加入登录授权认证功能,只有成功后,才能进入管理界面。

先在配置文件 WebConfig.cs 中加入

<authentication mode="Forms"> <forms loginUrl="~/Account/Login" timeout="2880"> <credentials passwordFormat="Clear"> <user name="admin" password="123"/> </credentials> </forms> </authentication>

WebConfig.cs

<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit go.microsoft.com/fwlink/?LinkId=301880 --> <configuration> <connectionStrings> <add name="EfDbContext" connectionString="server=.;database=TestDb;uid=sa;pwd=123" providerName="System.Data.SqlClient"/> </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="SendEmailName" value="943239005@qq.com"/> </appSettings> <system.web> <authentication mode="Forms"> <forms loginUrl="~/Account/Login" timeout="2880"> <credentials passwordFormat="Clear"> <user name="admin" password="123"/> </credentials> </forms> </authentication> <compilation debug="true" targetFramework="4.6.1"/> <maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">*@ <link rel="stylesheet" href="maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> @*<link href="~/Contents/Login/css/htmleaf-demo.css" rel="stylesheet" />*@ <style type="text/css"> @@import url(fonts.googleapis.com/css?family=Roboto:300); .login-page { margin: auto; padding: 8% 0 0; width: 360px; } .form { background: #FFFFFF; box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24); margin: 0 auto 100px; max-width: 360px; padding: 45px; position: relative; text-align: center; z-index: 1; } .form input { background: #f2f2f2; border: 0; box-sizing: border-box; font-family: "Roboto", sans-serif; font-size: 14px; margin: 0 0 15px; outline: 0; padding: 15px; width: 100%; } .form button { -webkit-transition: all 0.3 ease; background: #4CAF50; border: 0; color: #FFFFFF; cursor: pointer; font-family: "Microsoft YaHei", "Roboto", sans-serif; font-size: 14px; outline: 0; padding: 15px; text-transform: uppercase; transition: all 0.3 ease; width: 100%; } .form button:hover, .form button:active, .form button:focus { background: #43A047; } .form .message { color: #b3b3b3; font-size: 12px; margin: 15px 0 0; } .form .message a { color: #4CAF50; text-decoration: none; } .form .register-form { display: none; } .container { margin: 0 auto; max-width: 300px; position: relative; z-index: 1; } .container:before, .container:after { clear: both; content: ""; display: block; } .container .info { margin: 50px auto; text-align: center; } .container .info h1 { color: #1a1a1a; font-size: 36px; font-weight: 300; margin: 0 0 15px; padding: 0; } .container .info span { color: #4d4d4d; font-size: 12px; } .container .info span a { color: #000000; text-decoration: none; } .container .info span .fa { color: #EF3B3A; } body { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; background: #76b852; /* fallback for old browsers */ background: -webkit-linear-gradient(right, #76b852, #8DC26F); background: -moz-linear-gradient(right, #76b852, #8DC26F); background: -o-linear-gradient(right, #76b852, #8DC26F); background: linear-gradient(to left, #76b852, #8DC26F); font-family: "Roboto", sans-serif; } </style> <!--[if IE]> <script src="cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script> <![endif]--> <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/jquery.validate.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.js"></script> </head> <body> <div id="wrapper" class="login-page"> <div id="login_form" class="form"> @using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "login-form" })) { <span style="float: left; color: red;">@Html.ValidationSummary()</span> @Html.AntiForgeryToken() @Html.TextBoxFor(x => x.UserName, new { placeholder = "用户名" }) @Html.EditorFor(x => x.Password, new { placeholder = "密码", }) <input type="submit" value="登 录" /> } </div> </div> </body> </html>

ValidateAntiForgeryToken 特性用于防止跨站请求伪造(CSRF)攻击。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。

本文共计2791个文字,预计阅读时间需要12分钟。

如何一步步构建以长尾词为核心的MVC电商网站BooksStore?

逐步构建一个简单的MVC电子商务网站 - BooksStore(四)系列GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore《一步步构建一个简单的MVC电子商务网站 - BooksStore(一)》《一步步构建一个简单的MVC电子商务网站 - BooksStore(二)》《一步步构建一个简单的MVC电子商务网站 - BooksStore(三)》

一步步打造一个简单的 MVC 电商网站 - BooksStore(四)

本系列的 GitHub地址:github.com/liqingwen2015/Wen.BooksStore

《一步步打造一个简单的 MVC 电商网站 - BooksStore(一)》

《一步步打造一个简单的 MVC 电商网站 - BooksStore(二)》

《一步步打造一个简单的 MVC 电商网站 - BooksStore(三)》

《一步步打造一个简单的 MVC 电商网站 - BooksStore(四)》

简介

  上一节我们完成了两个主要功能:完成了整个购物车的流程,以及订单处理(发邮件进行通知),今天我们来学习一下最基本的增删改查,以及登录认证过滤器,加入防 CSRF 攻击,本系列已完结。

  该系列主要功能与知识点如下:

  分类、产品浏览、购物车、结算、CRUD(增删改查) 管理、发邮件、分页、模型绑定、认证过滤器和单元测试等。

项目使用 VS2015 + C#6 进行开发,有问题请发表在留言区哦,还有,页面长得比较丑,请见谅。

目录

基本的增删改查 CRUD

登录授权认证过滤

基本的增删改查 CRUD

我们创建一个新的控制器进行增删改查功能,AdminController,并添加一个显示所有数据的方法:

/// <summary> /// 后台管理控制器 /// </summary> public class AdminController : Controller { private readonly IBookRepository _bookRepository; public AdminController(IBookRepository bookRepository) { _bookRepository = bookRepository; } /// <summary> /// 首页 /// </summary> /// <returns></returns> public ActionResult Index() { return View(_bookRepository.Books); } }

不在沿用之前的布局页了,创建一个新的布局页 _AdmindLayout.cshtml:

<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> <link href="~/Contents/admin/Site.css" rel="stylesheet" /> </head> <body> <div> @RenderBody() </div> </body> </html>

Site.css

.table { width: 100%; padding: 0; margin: 0; } .table th { font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; color: #4f6b72; border-right: 1px solid #C1DAD7; border-bottom: 1px solid #C1DAD7; border-top: 1px solid #C1DAD7; letter-spacing: 2px; text-transform: uppercase; text-align: left; padding: 6px 6px 6px 12px; background: #CAE8EA no-repeat; } .table td { border-right: 1px solid #C1DAD7; border-bottom: 1px solid #C1DAD7; background: #fff; font-size: 14px; padding: 6px 6px 6px 12px; color: #4f6b72; } .table td.alt { background: #F5FAFA; color: #797268; } .table th.spec, td.spec { border-left: 1px solid #C1DAD7; }

对应的Index.cshtml:

@model IEnumerable<Wen.BooksStore.Domain.Entities.Book> @{ Layout = "~/Views/Shared/_AdminLayout.cshtml"; } <p> @Html.ActionLink("新增", "Edit") </p> <table class="table"> <tr> <th> 名称 </th> <th> 描述 </th> <th> 价格 </th> <th> 分类 </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Description) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.DisplayFor(modelItem => item.Category) </td> <td> @Html.ActionLink("编辑", "Edit", new { id = item.Id }) @using (Html.BeginForm("Delete", "Admin", FormMethod.Post, new { style = "display:inline;" })) { @Html.Hidden("id", item.Id) <input type="submit" value="删除" /> } </td> </tr> } </table>

编辑,我把新增和编辑的位置放在一块,使用 id 进行区分,如果 id = 0 就表示新增的信息。

在 AdminCtroller 中添加关于编辑的方法

/// <summary> /// 编辑 /// </summary> /// <param name="id"></param> /// <returns></returns> public ActionResult Edit(int id = 0) { if (id == 0) { return View(new Book()); } var model = _bookRepository.Books.FirstOrDefault(x => x.Id == id); return View(model); } /// <summary> /// 编辑 /// </summary> /// <param name="book"></param> /// <returns></returns> [HttpPost] public ActionResult Edit(Book book) { if (!ModelState.IsValid) { return View(book); } _bookRepository.SaveBook(book); return RedirectToAction("Index"); }

更新存储库中的方法:

IBookRepository.cs

/// <summary> /// 书存储库接口 /// </summary> public interface IBookRepository { /// <summary> /// 书模型集合 /// </summary> IQueryable<Book> Books { get; } /// <summary> /// 保存书 /// </summary> /// <param name="book"></param> /// <returns></returns> int SaveBook(Book book); /// <summary> /// 删除书 /// </summary> /// <param name="id"></param> /// <returns></returns> Book DeleteBook(int id); }

EfBookRepository.cs

/// <summary> /// 书存储库 /// </summary> public class EfBookRepository : IBookRepository { private readonly EfDbContext _context = new EfDbContext(); /// <summary> /// 书模型集合 /// </summary> public IQueryable<Book> Books => _context.Books; /// <summary> /// 保存书 /// </summary> /// <param name="book"></param> /// <returns></returns> public int SaveBook(Book book) { if (book.Id == 0) { _context.Books.Add(book); } else { var model = _context.Books.Find(book.Id); if (model==null) { return 0; } model.Category = book.Category; model.Description = book.Description; model.Name = book.Name; model.Price = book.Price; } return _context.SaveChanges(); } /// <summary> /// 删除书 /// </summary> /// <param name="id"></param> /// <returns></returns> public Book DeleteBook(int id) { var model = _context.Books.Find(id); if (model == null) { return null; } _context.Books.Remove(model); _context.SaveChanges(); return model; } }

需要对 Book 模型加上验证用的特性:

[Table("Book")] public class Book { /// <summary> /// 标识 /// </summary> public int Id { get; set; } /// <summary> /// 名称 /// </summary> [Required(ErrorMessage = "名称不能为空")] public string Name { get; set; } /// <summary> /// 描述 /// </summary> [Required(ErrorMessage = "描述不能为空")] public string Description { get; set; } /// <summary> /// 价格 /// </summary> [Required(ErrorMessage = "价格不能为空")] [Range(0.01, double.MaxValue, ErrorMessage = "请填写合适的价格")] public decimal Price { get; set; } /// <summary> /// 分类 /// </summary> [Required(ErrorMessage = "分类不能为空")] public string Category { get; set; } }

_AdminLayout.cshtml 需要引入验证用的 js(客户端验证):

如何一步步构建以长尾词为核心的MVC电商网站BooksStore?

<script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/jquery.validate.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

Edit.cshtml

@model Wen.BooksStore.Domain.Entities.Book @{ Layout = "~/Views/Shared/_AdminLayout.cshtml"; } <h2>编辑</h2> <div> @Html.ValidationSummary() <div> @using (Html.BeginForm()) { @Html.HiddenFor(x => x.Id) <table> <tr> <td>名称</td> <td>@Html.TextBoxFor(x => x.Name)</td> </tr> <tr> <td>价格</td> <td>@Html.TextBoxFor(x => x.Price)</td> </tr> <tr> <td>分类</td> <td>@Html.TextBoxFor(x => x.Category)</td> </tr> <tr> <td>描述</td> <td>@Html.TextAreaFor(x => x.Description)</td> </tr> </table> <input type="submit" value="提交" /> } </div> </div>

图:错误提示

删除

/// <summary> /// 删除 /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpPost] public ActionResult Delete(int id) { _bookRepository.DeleteBook(id); return RedirectToAction("Index"); }

加入提示,我们在新增、编辑和删除时应该加入必要的提示信息,使用TempData。

/Admin/Index.cshtml 下的也要添加:

执行效果:

TempData 临时数据保存了一条信息,是一个“键/值”字典,类似会话 Session 和 ViewBag,它和 Session 的差别是,在 HTTP 请求结束后会被删除。因为这里使用了 RedirectToAction ,一条重定向指令,会告诉浏览器重定向请求到一个新地址,这时就不能使用 ViewBag,ViewBag 用于在控制器与视图之间传递数据,但它保持数据的时间不能比当前的HTTP 请求长,重定向意味着用户是跨请求的,ViewBag 不能用于跨请求时传递数据。

登录授权认证过滤

上面是一个 Admin 的后台管理操作,不是每一个用户都能够进入管理的,所以现在加入登录授权认证功能,只有成功后,才能进入管理界面。

先在配置文件 WebConfig.cs 中加入

<authentication mode="Forms"> <forms loginUrl="~/Account/Login" timeout="2880"> <credentials passwordFormat="Clear"> <user name="admin" password="123"/> </credentials> </forms> </authentication>

WebConfig.cs

<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit go.microsoft.com/fwlink/?LinkId=301880 --> <configuration> <connectionStrings> <add name="EfDbContext" connectionString="server=.;database=TestDb;uid=sa;pwd=123" providerName="System.Data.SqlClient"/> </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="SendEmailName" value="943239005@qq.com"/> </appSettings> <system.web> <authentication mode="Forms"> <forms loginUrl="~/Account/Login" timeout="2880"> <credentials passwordFormat="Clear"> <user name="admin" password="123"/> </credentials> </forms> </authentication> <compilation debug="true" targetFramework="4.6.1"/> <maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">*@ <link rel="stylesheet" href="maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> @*<link href="~/Contents/Login/css/htmleaf-demo.css" rel="stylesheet" />*@ <style type="text/css"> @@import url(fonts.googleapis.com/css?family=Roboto:300); .login-page { margin: auto; padding: 8% 0 0; width: 360px; } .form { background: #FFFFFF; box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24); margin: 0 auto 100px; max-width: 360px; padding: 45px; position: relative; text-align: center; z-index: 1; } .form input { background: #f2f2f2; border: 0; box-sizing: border-box; font-family: "Roboto", sans-serif; font-size: 14px; margin: 0 0 15px; outline: 0; padding: 15px; width: 100%; } .form button { -webkit-transition: all 0.3 ease; background: #4CAF50; border: 0; color: #FFFFFF; cursor: pointer; font-family: "Microsoft YaHei", "Roboto", sans-serif; font-size: 14px; outline: 0; padding: 15px; text-transform: uppercase; transition: all 0.3 ease; width: 100%; } .form button:hover, .form button:active, .form button:focus { background: #43A047; } .form .message { color: #b3b3b3; font-size: 12px; margin: 15px 0 0; } .form .message a { color: #4CAF50; text-decoration: none; } .form .register-form { display: none; } .container { margin: 0 auto; max-width: 300px; position: relative; z-index: 1; } .container:before, .container:after { clear: both; content: ""; display: block; } .container .info { margin: 50px auto; text-align: center; } .container .info h1 { color: #1a1a1a; font-size: 36px; font-weight: 300; margin: 0 0 15px; padding: 0; } .container .info span { color: #4d4d4d; font-size: 12px; } .container .info span a { color: #000000; text-decoration: none; } .container .info span .fa { color: #EF3B3A; } body { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; background: #76b852; /* fallback for old browsers */ background: -webkit-linear-gradient(right, #76b852, #8DC26F); background: -moz-linear-gradient(right, #76b852, #8DC26F); background: -o-linear-gradient(right, #76b852, #8DC26F); background: linear-gradient(to left, #76b852, #8DC26F); font-family: "Roboto", sans-serif; } </style> <!--[if IE]> <script src="cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script> <![endif]--> <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/jquery.validate.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.js"></script> </head> <body> <div id="wrapper" class="login-page"> <div id="login_form" class="form"> @using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "login-form" })) { <span style="float: left; color: red;">@Html.ValidationSummary()</span> @Html.AntiForgeryToken() @Html.TextBoxFor(x => x.UserName, new { placeholder = "用户名" }) @Html.EditorFor(x => x.Password, new { placeholder = "密码", }) <input type="submit" value="登 录" /> } </div> </div> </body> </html>

ValidateAntiForgeryToken 特性用于防止跨站请求伪造(CSRF)攻击。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。