栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > asp

一步步打造简单的MVC电商网站BooksStore(4)

asp 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

一步步打造简单的MVC电商网站BooksStore(4)

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

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

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

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

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

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

简介

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

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

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

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

目录

基本的增删改查 CRUD

登录授权认证过滤

基本的增删改查 CRUD

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

/// 
 /// 后台管理控制器
 /// 
 public class AdminController : Controller
 {
 private readonly IBookRepository _bookRepository;

 public AdminController(IBookRepository bookRepository)
 {
  _bookRepository = bookRepository;
 }

 /// 
 /// 首页
 /// 
 /// 
 public ActionResult Index()
 {
  return View(_bookRepository.Books);
 }
 }

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





 
 @ViewBag.Title
 


 
 @RenderBody()
 



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

@{
 Layout = "~/Views/Shared/_AdminLayout.cshtml";
}

@Html.Actionlink("新增", "Edit")

@foreach (var item in Model) { }
名称 描述 价格 分类
@Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.Description) @Html.DisplayFor(modelItem => item.Price) @Html.DisplayFor(modelItem => item.Category) @Html.Actionlink("编辑", "Edit", new { id = item.Id }) @using (Html.BeginForm("Delete", "Admin", FormMethod.Post, new { style = "display:inline;" })) { @Html.Hidden("id", item.Id) }

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

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

/// 
 /// 编辑
 /// 
 /// 
 /// 
 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);
 }

 /// 
 /// 编辑
 /// 
 /// 
 /// 
 [HttpPost]
 public ActionResult Edit(Book book)
 {
  if (!ModelState.IsValid)
  {
  return View(book);
  }

  _bookRepository.SaveBook(book);
  return RedirectToAction("Index");
 }

更新存储库中的方法:

IBookRepository.cs

/// 
 /// 书存储库接口
 /// 
 public interface IBookRepository
 {
 /// 
 /// 书模型集合
 /// 
 IQueryable Books { get; }

 /// 
 /// 保存书
 /// 
 /// 
 /// 
 int SaveBook(Book book);

 /// 
 /// 删除书
 /// 
 /// 
 /// 
 Book DeleteBook(int id);
 }

EfBookRepository.cs

/// 
 /// 书存储库
 /// 
 public class EfBookRepository : IBookRepository
 {
 private readonly EfDbContext _context = new EfDbContext();

 /// 
 /// 书模型集合
 /// 
 public IQueryable Books => _context.Books;

 /// 
 /// 保存书
 /// 
 /// 
 /// 
 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();
 }

 /// 
 /// 删除书
 /// 
 /// 
 /// 
 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
 {
 /// 
 /// 标识
 /// 
 public int Id { get; set; }

 /// 
 /// 名称
 /// 
 [Required(ErrorMessage = "名称不能为空")]
 public string Name { get; set; }

 /// 
 /// 描述
 /// 
 [Required(ErrorMessage = "描述不能为空")]
 public string Description { get; set; }

 /// 
 /// 价格
 /// 
 [Required(ErrorMessage = "价格不能为空")]
 [Range(0.01, double.MaxValue, ErrorMessage = "请填写合适的价格")]
 public decimal Price { get; set; }

 /// 
 /// 分类
 /// 
 [Required(ErrorMessage = "分类不能为空")]
 public string Category { get; set; }
 }

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





Edit.cshtml

@model Wen.BooksStore.Domain.Entities.Book

@{
 Layout = "~/Views/Shared/_AdminLayout.cshtml";
}

编辑


 @Html.ValidationSummary()

 
 @using (Html.BeginForm())
 {
  @Html.HiddenFor(x => x.Id)
  
名称 @Html.TextBoxFor(x => x.Name)
价格 @Html.TextBoxFor(x => x.Price)
分类 @Html.TextBoxFor(x => x.Category)
描述 @Html.textareaFor(x => x.Description)
}

图:错误提示

删除

/// 
 /// 删除
 /// 
 /// 
 /// 
 [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 中加入


 
 
  
 
 

WebConfig.cs




 
 
 

 
 
 
 
 
 
 
 
 
 
 
  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 


  在这里使用的授权认证模式为表单认证,为了简化与数据库的交互操作,采取的是硬编码的形式。如果尚未得到认证,会跳转到 Account/Login 的地址让管理员先进行登录,timeout 表示登录(即认证)成功的保持时长为 2880 分钟(即 48 小时),而 name 表示的就是用户名, password 表示的就是登录密码。  

  这里采用的是授权认证过滤器,我们需要对要认证后才能进入的控制器添加一个特性[Authorize],即对 AdminController 添加该特性。

新建表单认证提供器,一个接口和一个实现:

IAuthProvider.cs:

public interface IAuthProvider
 {
 /// 
 /// 认证
 /// 
 /// 
 /// 
 /// 
 bool Auth(string userName, string password);
 }

FormsAuthProvider.cs:

/// 
 /// 表单认证提供者
 /// 
 public class FormsAuthProvider:IAuthProvider
 {
 /// 
 /// 认证
 /// 
 /// 
 /// 
 /// 
 public bool Auth(string userName, string password)
 {
  var result = FormsAuthentication.Authenticate(userName, password);

  if (result)
  {
  //设置认证 cookie
  FormsAuthentication.SetAuthcookie(userName, false);
  }

  return result;
 }
 }

AddBindings() 方法中注册:

/// 
 /// 添加绑定
 /// 
 private void AddBindings()
 {
  _kernel.Bind().To();
  _kernel.Bind().To();
  _kernel.Bind().To();
 }

/// 
 /// 登录视图模型
 /// 
 public class LoginViewModel
 {
 [Required(ErrorMessage = "用户名不能为空")]
 public string UserName { get; set; }

 [Required(ErrorMessage = "密码不能为空")]
 [DataType(DataType.Password)]
 public string Password { get; set; }
 }

新建 AccountController

public class AccountController : Controller
 {
 private readonly IAuthProvider _authProvider;

 public AccountController(IAuthProvider authProvider)
 {
  _authProvider = authProvider;
 }

 /// 
 /// 登录
 /// 
 /// 
 public ActionResult Login()
 {
  return View();
 }

 /// 
 /// 登录
 /// 
 /// 
 /// 
 [HttpPost]
 [ValidateAntiForgeryToken]
 public ActionResult Login(LoginViewModel model)
 {
  if (!ModelState.IsValid)
  {
  return View(new LoginViewModel());
  }

  var result = _authProvider.Auth(model.UserName, model.Password);
  if (result) return RedirectToAction("Index", "Admin");

  ModelState.AddModelError("", "账号或用户名有误");
  return View(new LoginViewModel());
 }
 }

Login.cshtml 登录页面:

@model Wen.BooksStore.WebUI.Models.LoginViewModel
@{
 Layout = null;
}




 
 
 
 登录
 @**@
 
 @**@
 
 @@import url(https://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; 
  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;
 }
 
 
 
 
 


 
 
  @using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "login-form" }))
  {
  @Html.ValidationSummary()
  @Html.AntiForgeryToken()
  @Html.TextBoxFor(x => x.UserName, new { placeholder = "用户名" })
  @Html.EditorFor(x => x.Password, new { placeholder = "密码", })

  
  }

 
 



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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/55646.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号