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

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

 更新時間:2017年04月06日 11:51:06   作者:反骨仔  
這篇文章主要和大家一起一步步打造一個簡單的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(四)

簡介

主要功能與知識點如下:

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

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

目錄

  • 創(chuàng)建項目架構(gòu)
  • 創(chuàng)建域模型實體
  • 創(chuàng)建單元測試
  • 創(chuàng)建控制器與視圖
  • 創(chuàng)建分頁
  • 加入樣式

一、創(chuàng)建項目架構(gòu)

1.新建一個解決方案“BooksStore”,并添加以下項目:

BooksStore.Domain:類庫,存放域模型和邏輯,使用 EF; BooksStore.WebUI:Web MVC 應用程序,存放視圖和控制器,充當顯示層,使用了 Ninject 作為 DI 容器; BoosStore.UnitTest:單元測試,對上述兩個項目進行測試?! ?/p>

Web MVC 為一個空的 MVC 項目:

2.添加項目引用(需要使用 NuGet):

這是不同項目需要引用的類庫和項目

3.設(shè)置 DI 容器

我們通過 Ninject ,創(chuàng)建一個自定義的工廠,一個名為NinjectControllerFactory 的類繼承DefaultControllerFactory(默認的控制器工廠)。你也可以在里面添加自定義的代碼,改變 MVC 框架的默認行為。

AddBindings() 添加綁定方法,先留空。

public class NinjectControllerFactory : DefaultControllerFactory
 {
 private readonly IKernel _kernel;

 public NinjectControllerFactory()
 {
  _kernel = new StandardKernel();
  AddBindings();
 }

 protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
 {
  return controllerType == null
  ? null
  : (IController) _kernel.Get(controllerType);
 }

 /// <summary>
 /// 添加綁定
 /// </summary>
 private void AddBindings()
 {
  
 }
 }

4.并且在 Global.asax 中加入一行代碼,告訴 MVC 用新建的類來創(chuàng)建控制器對象。

ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

public class MvcApplication : System.Web.HttpApplication
 {
 protected void Application_Start()
 {
  AreaRegistration.RegisterAllAreas();
  RouteConfig.RegisterRoutes(RouteTable.Routes);

  ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
 }
 }

二、創(chuàng)建域模型實體

1.在圖中位置創(chuàng)建一個名為 Book 的實體類。

public class Book
 {
 /// <summary>
 /// 標識
 /// </summary>
 public int Id { get; set; }

 /// <summary>
 /// 名稱
 /// </summary>
 public string Name { get; set; }

 /// <summary>
 /// 描述
 /// </summary>
 public string Description { get; set; }

 /// <summary>
 /// 價格
 /// </summary>
 public decimal Price { get; set; }

 /// <summary>
 /// 分類
 /// </summary>
 public string Category { get; set; }
 }

有了實體之后,我們應該創(chuàng)建一個“庫”對該實體進行操作,而這種持久化邏輯操作也應該和域模型是進行隔離的。

2.先定義一個接口 IbookRepository,在根目錄創(chuàng)建一個名為 Abstract 的文件夾,顧名思義就是應該放置一些抽象的類,如接口。

public interface IBookRepository
 {
 IQueryable<Book> Books { get; }
 }

我們通過該接口就可以得到對應類的相關(guān)信息,而不需要去管該數(shù)據(jù)如何存儲,以及存儲的位置,這就是存儲庫模式的本質(zhì)。

3.接下來,我們就需要對數(shù)據(jù)庫進行操作了,我們使用簡單的EF(ORM 對象關(guān)系模型) 去對數(shù)據(jù)庫進行操作,所以需要自己通過 Nuget 下載 EF 的類庫。

4.因為之前定義了接口類,接下來就應該定義實現(xiàn)該接口的類了

  安裝完之后,再次建立一個名為 Concrete 的文件夾,存放實例。

  在里面創(chuàng)建一個 EfDbContext 的類,派生于 DbContext,該類會為用戶要使用的數(shù)據(jù)庫中的每個表自動的定義一個屬性。該屬性名為 Books,指定了表名,DbSet<Book> 表示為 Book 實體的表模型,Book 對象相當于 Books 表中的行(記錄)。

 public class EfDbContext : DbContext
 {
 public DbSet<Book> Books { get; set; }
 }

  再創(chuàng)建一個EfBookRepository 存儲庫類,它實現(xiàn) IBookRepository 接口,使用了上文創(chuàng)建的 EfDbContext 上下文對象,包含了具體的方法定義。

public class EfBookRepository : IBookRepository
 {
 private readonly EfDbContext _context = new EfDbContext();

 public IQueryable<Book> Books => _context.Books;
 }

5.現(xiàn)在只差在數(shù)據(jù)庫新建一張表了。

CREATE TABLE Book
(
 Id INT IDENTITY PRIMARY KEY,
 Name NVARCHAR(100),
 Description NVARCHAR(MAX),
 Price DECIMAL,
 Category NVARCHAR(50)
)

并插入測試數(shù)據(jù):

INSERT INTO dbo.Book
 ( 
  Name ,
  Description ,
  Price ,
  Category
 )
VALUES ( 
  N'C#從入門到精通' , -- Name - nvarchar(100)
  N'好書-C#從入門到精通' , -- Description - nvarchar(max)
, -- Price - decimal
  N'.NET' -- Category - nvarchar(50)
 )

INSERT INTO dbo.Book
 ( 
  Name ,
  Description ,
  Price ,
  Category
 )
VALUES ( 
  N'ASP.NET從入門到精通' , -- Name - nvarchar(100)
  N'好書-ASP.NET從入門到精通' , -- Description - nvarchar(max)
, -- Price - decimal
  N'.NET' -- Category - nvarchar(50)
 )

INSERT INTO dbo.Book
 ( 
  Name ,
  Description ,
  Price ,
  Category
 )
VALUES ( 
  N'多線程從入門到精通' , -- Name - nvarchar(100)
  N'好書-多線程從入門到精通' , -- Description - nvarchar(max)
, -- Price - decimal
  N'.NET' -- Category - nvarchar(50)
 )

INSERT INTO dbo.Book
 ( 
  Name ,
  Description ,
  Price ,
  Category
 )
VALUES ( 
  N'java從入門到放棄' , -- Name - nvarchar(100)
  N'好書-java從入門到放棄' , -- Description - nvarchar(max)
, -- Price - decimal
  N'java' -- Category - nvarchar(50)
 )

INSERT INTO dbo.Book
 ( 
  Name ,
  Description ,
  Price ,
  Category
 )
VALUES ( 
  N'sql從入門到放棄' , -- Name - nvarchar(100)
  N'好書-sql從入門到放棄' , -- Description - nvarchar(max)
, -- Price - decimal
  N'sql' -- Category - nvarchar(50)
 )

INSERT INTO dbo.Book
 ( 
  Name ,
  Description ,
  Price ,
  Category
 )
VALUES ( 
  N'sql從入門到出家' , -- Name - nvarchar(100)
  N'好書-sql從入門到出家' , -- Description - nvarchar(max)
, -- Price - decimal
  N'sql' -- Category - nvarchar(50)
 )

INSERT INTO dbo.Book
 ( 
  Name ,
  Description ,
  Price ,
  Category
 )
VALUES ( 
  N'php從入門到出家' , -- Name - nvarchar(100)
  N'好書-php從入門到出家' , -- Description - nvarchar(max)
, -- Price - decimal
  N'php' -- Category - nvarchar(50)
 )

測試數(shù)據(jù)

因為我希望表名為 Book,而不是 Books,所以我在之前的 Book 類上加上特性 [Table("Book")]:

三、創(chuàng)建單元測試

1.做完預熱操作后,你可能想立即以界面的的方式進行顯示,別急,先用單元測試檢查一下我們對數(shù)據(jù)庫的操作是否正常,通過對數(shù)據(jù)進行簡單的讀取,檢查下連接是否成功。

2.單元測試也需要引入 ef 類庫(Nuget)。

3.安裝完之后會生成一個 app.config 配置文件,需要額外添加一行連接字符串(在后續(xù)的 Web UI 項目里,也需要加上這條信息,不然會提示對應的錯誤信息)。

<connectionStrings>
 <add name="EfDbContext" connectionString="server=.;database=TestDb;uid=sa;pwd=123" providerName="System.Data.SqlClient"/>
 </connectionStrings>

4.當所有前置工作都準備好了的時候,就應該填寫測試方法了,因為我插入了 7 條數(shù)據(jù),這里我就判斷一下從數(shù)據(jù)庫讀取出的行數(shù)是否為 7 :

[TestMethod]
 public void BooksCountTest()
 {
  var bookRepository=new EfBookRepository();
  var books = bookRepository.Books;

  Assert.AreEqual(books.Count(),7);
 }

5.在該方法體的內(nèi)部單擊右鍵,你可以看到一個“運行測試”的選項,這時你可以嘗試單擊它:

從這個符號可以看到,是成功了!

接下來,我們要正式從頁面顯示我們想要的信息了。

四、創(chuàng)建控制器與視圖 

1.先新建一個空的控制器:BookController:

2.需要我們自定義一個 Details 方法,用于后續(xù)與界面進行交互。

public class BookController : Controller
 {
 private readonly IBookRepository _bookRepository;

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

 /// <summary>
 /// 詳情
 /// </summary>
 /// <returns></returns>
 public ActionResult Details()
 {
  return View(_bookRepository.Books);
 }
 }

3.接下來,要創(chuàng)建一個視圖 View 了。

4.將 Details.cshtml 的內(nèi)容替換為下面的:

@model IEnumerable<Wen.BooksStore.Domain.Entities.Book>

@{
 ViewBag.Title = "Books";
}


@foreach (var item in Model)
{
 <div>
 <h3>@item.Name</h3>
 @item.Description
 <h4>@item.Price.ToString("C")</h4>
 <br />
 <hr />
 </div>
}

5.改下默認的路由機制,讓他默認跳轉(zhuǎn)到該頁面。

6.還有一點需要注意的是,因為我們使用了 Ninject 容器,并且需要對控制器中的構(gòu)造函數(shù)中的參數(shù)IBookRepository 進行解析,告訴他將使用哪個對象對該接口進行服務(wù),也就是需要修改之前的 AddBindings 方法:

7.運行的效果大致如下(因為加了點 CSS 樣式,所以顯示的效果可能有些許不同),結(jié)果是一致的。

五、創(chuàng)建分頁

1.在 Models 文件夾新增一個 PagingInfo.cs 分頁信息類。

/// <summary>
 /// 分頁信息
 /// </summary>
 public class PagingInfo
 {
 /// <summary>
 /// 總數(shù)
 /// </summary>
 public int TotalItems { get; set; }

 /// <summary>
 /// 頁容量
 /// </summary>
 public int PageSize { get; set; }

 /// <summary>
 /// 當前頁
 /// </summary>
 public int PageIndex { get; set; }

 /// <summary>
 /// 總頁數(shù)
 /// </summary>
 public int TotalPages => (int)Math.Ceiling((decimal)TotalItems / PageSize);
 }

2.新增一個 HtmlHelpers 文件夾存放一個基于 Html 幫助類的擴展方法:

public static class PagingHelper
 {
 /// <summary>
 /// 分頁
 /// </summary>
 /// <param name="helper"></param>
 /// <param name="pagingInfo"></param>
 /// <param name="func"></param>
 /// <returns></returns>
 public static MvcHtmlString PageLinks(this HtmlHelper helper, PagingInfo pagingInfo, Func<int, string> func)
 {
  var sb = new StringBuilder();
  for (var i = 1; i <= pagingInfo.TotalPages; i++)
  {
  //創(chuàng)建 <a> 標簽
  var tagBuilder = new TagBuilder("a");
  //添加特性
  tagBuilder.MergeAttribute("href", func(i));
  //添加值
  tagBuilder.InnerHtml = i.ToString();

  if (i == pagingInfo.PageIndex)
  {
   tagBuilder.AddCssClass("selected");
  }

  sb.Append(tagBuilder);
  }

  return MvcHtmlString.Create(sb.ToString());
 }
 }

3.添加完畢后需要在配置文件內(nèi)加入該命名空間

4.現(xiàn)在要重新修改BookController.cs 控制器內(nèi)的的代碼,并添加新的視圖模型類BookDetailsViewModels.cs,讓它繼承之前的分頁類。

public class BookDetailsViewModels : PagingInfo
 {
 public IEnumerable<Book> Books { get; set; }
 }

修改后的控制器代碼:

public class BookController : Controller
 {
 private readonly IBookRepository _bookRepository;
 public int PageSize = 5;

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

 /// <summary>
 /// 詳情
 /// </summary>
 /// <param name="pageIndex"></param>
 /// <returns></returns>
 public ActionResult Details(int pageIndex = 1)
 {
  var model = new BookDetailsViewModels()
  {
  Books = _bookRepository.Books.OrderBy(x => x.Id).Skip((pageIndex - 1) * PageSize).Take(PageSize),
  PageSize = PageSize,
  PageIndex = pageIndex,
  TotalItems = _bookRepository.Books.Count()
  };

  return View(model);
 }
 }

5.修改視圖模型后,對應的視圖頁也需要修改

@model Wen.BooksStore.WebUI.Models.BookDetailsViewModels

@{
 ViewBag.Title = "Books";
}


@foreach (var item in Model.Books)
{
 <div>
 <h3>@item.Name</h3>
 @item.Description
 <h4>@item.Price.ToString("C")</h4>
 <br />
 <hr />
 </div>
}

<div class="pager">
 @Html.PageLinks(Model, x => Url.Action("Details", new { pageIndex = x }))
</div>

六、加入樣式

1.頁面的樣式簡單的設(shè)計為 3 大板塊,頂部為標題,左側(cè)邊欄為分類,主模塊將顯示具體內(nèi)容。

我們現(xiàn)在要在 Views 文件夾下創(chuàng)建一個文件 _ViewStart.cshtml,再創(chuàng)建一個 Shared 的文件夾和文件 _Layout.cshtml。

2._Layout.cshtml 這是布局頁,當代碼執(zhí)行到 @RenderBody() 時,就會負責將之前 Details.cshtml 的內(nèi)容進行渲染:

<!DOCTYPE html>

<html>
<head>
 <meta name="viewport" content="width=device-width" />
 <title>@ViewBag.Title</title>
 <link href="~/Contents/Site.css" rel="stylesheet" />
</head>
<body>
 <div id="header">
 <div class="title">圖書商城</div>
 </div>
 <div id="sideBar">分類</div>
 <div id="content">
 @RenderBody()
 </div>
</body>
</html>

_ViewStart.cshtml 該文件表示默認的布局頁為該視圖文件:

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

3.網(wǎng)站的根目錄下也要添加一個名為 Contents 的文件夾,用于存放 CSS。

body {
}

#header, #content, #sideBar {
 display: block;
}

#header {
 background-color: green;
 border-bottom: 2px solid #111;
 color: White;
}

#header, .title {
 font-size: 1.5em;
 padding: .5em;
}

#sideBar {
 float: left;
 width: 8em;
 padding: .3em;
}

#content {
 border-left: 2px solid gray;
 margin-left: 10em;
 padding: 1em;
}

.pager {
 text-align: right;
 padding: .5em 0 0 0;
 margin-top: 1em;
}

 .pager A {
 font-size: 1.1em;
 color: #666;
 padding: 0 .4em 0 .4em;
 }

 .pager A:hover {
  background-color: Silver;
 }

 .pager A.selected {
  background-color: #353535;
  color: White;
 }

現(xiàn)在,分頁也已經(jīng)有了效果,基本界面就出來了。

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

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

相關(guān)文章

最新評論