欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一步步打造簡單的MVC電商網(wǎng)站BooksStore(4)

 更新時間:2017年04月06日 16:25:12   作者:反骨仔  
這篇文章主要和大家一起一步步打造一個簡單的MVC電商網(wǎng)站,MVC電商網(wǎng)站BooksStore第四篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(四)

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

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(一)

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(二)

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(三)

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(四)

簡介

  上一節(jié)我們完成了兩個主要功能:完成了整個購物車的流程,以及訂單處理(發(fā)郵件進行通知),今天我們來學(xué)習一下最基本的增刪改查,以及登錄認證過濾器,加入防 CSRF 攻擊,本系列已完結(jié)。

  該系列主要功能與知識點如下:

  分類、產(chǎn)品瀏覽、購物車、結(jié)算、CRUD(增刪改查) 管理、發(fā)郵件、分頁、模型綁定、認證過濾器和單元測試等。

【備注】項目使用 VS2015 + C#6 進行開發(fā),有問題請發(fā)表在留言區(qū)哦,還有,頁面長得比較丑,請見諒。

目錄

基本的增刪改查 CRUD

登錄授權(quán)認證過濾

基本的增刪改查 CRUD

我們創(chuàng)建一個新的控制器進行增刪改查功能,AdminController,并添加一個顯示所有數(shù)據(jù)的方法:

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

不在沿用之前的布局頁了,創(chuàng)建一個新的布局頁 _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;
 }

對應(yīng)的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 進行區(qū)分,如果 id = 0 就表示新增的信息。

在 AdminCtroller 中添加關(guān)于編輯的方法

/// <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 = "請?zhí)顚懞线m的價格")]
 public decimal Price { get; set; }

 /// <summary>
 /// 分類
 /// </summary>
 [Required(ErrorMessage = "分類不能為空")]
 public string Category { get; set; }
 }

_AdminLayout.cshtml 需要引入驗證用的 js(客戶端驗證):

<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");
 }

加入提示,我們在新增、編輯和刪除時應(yīng)該加入必要的提示信息,使用TempData。

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

執(zhí)行效果:

【備注】TempData 臨時數(shù)據(jù)保存了一條信息,是一個“鍵/值”字典,類似會話 Session 和 ViewBag,它和 Session 的差別是,在 HTTP 請求結(jié)束后會被刪除。因為這里使用了 RedirectToAction ,一條重定向指令,會告訴瀏覽器重定向請求到一個新地址,這時就不能使用 ViewBag,ViewBag 用于在控制器與視圖之間傳遞數(shù)據(jù),但它保持數(shù)據(jù)的時間不能比當前的HTTP 請求長,重定向意味著用戶是跨請求的,ViewBag 不能用于跨請求時傳遞數(shù)據(jù)。

登錄授權(quán)認證過濾

上面是一個 Admin 的后臺管理操作,不是每一個用戶都能夠進入管理的,所以現(xiàn)在加入登錄授權(quán)認證功能,只有成功后,才能進入管理界面。

先在配置文件 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
 http://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"/>
 <httpRuntime targetFramework="4.6.1"/>
 <httpModules>
 <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
 </httpModules>
 </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.3.0" newVersion="5.2.3.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=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
 warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"/>
 <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
 type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
 warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
 </compilers>
 </system.codedom>
 <system.webServer>

 <validation validateIntegratedModeConfiguration="false"/>
 <modules>
 <remove name="ApplicationInsightsWebTracking"/>
 <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"
 preCondition="managedHandler"/>
 </modules>
 </system.webServer>
</configuration>

  在這里使用的授權(quán)認證模式為表單認證,為了簡化與數(shù)據(jù)庫的交互操作,采取的是硬編碼的形式。如果尚未得到認證,會跳轉(zhuǎn)到 Account/Login 的地址讓管理員先進行登錄,timeout 表示登錄(即認證)成功的保持時長為 2880 分鐘(即 48 小時),而 name 表示的就是用戶名, password 表示的就是登錄密碼?! ?/p>

  這里采用的是授權(quán)認證過濾器,我們需要對要認證后才能進入的控制器添加一個特性[Authorize],即對 AdminController 添加該特性。

新建表單認證提供器,一個接口和一個實現(xiàn):

IAuthProvider.cs:

public interface IAuthProvider
 {
 /// <summary>
 /// 認證
 /// </summary>
 /// <param name="userName"></param>
 /// <param name="password"></param>
 /// <returns></returns>
 bool Auth(string userName, string password);
 }

FormsAuthProvider.cs:

/// <summary>
 /// 表單認證提供者
 /// </summary>
 public class FormsAuthProvider:IAuthProvider
 {
 /// <summary>
 /// 認證
 /// </summary>
 /// <param name="userName"></param>
 /// <param name="password"></param>
 /// <returns></returns>
 public bool Auth(string userName, string password)
 {
  var result = FormsAuthentication.Authenticate(userName, password);

  if (result)
  {
  //設(shè)置認證 Cookie
  FormsAuthentication.SetAuthCookie(userName, false);
  }

  return result;
 }
 }

AddBindings() 方法中注冊:

/// <summary>
 /// 添加綁定
 /// </summary>
 private void AddBindings()
 {
  _kernel.Bind<IBookRepository>().To<EfBookRepository>();
  _kernel.Bind<IOrderProcessor>().To<EmailOrderProcessor>();
  _kernel.Bind<IAuthProvider>().To<FormsAuthProvider>();
 }

/// <summary>
 /// 登錄視圖模型
 /// </summary>
 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;
 }

 /// <summary>
 /// 登錄
 /// </summary>
 /// <returns></returns>
 public ActionResult Login()
 {
  return View();
 }

 /// <summary>
 /// 登錄
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 [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;
}

<!DOCTYPE html>
<html lang="zh">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>登錄</title>
 @*<link rel="stylesheet" >*@
 <link rel="stylesheet" >
 @*<link href="~/Contents/Login/css/htmleaf-demo.css" rel="stylesheet" />*@
 <style type="text/css">
 @@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; /* 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="http://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)攻擊。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論