激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - 一步步打造簡單的MVC電商網站BooksStore(2)

一步步打造簡單的MVC電商網站BooksStore(2)

2020-04-30 12:17反骨仔 ASP.NET教程

這篇文章主要和大家一起一步步打造一個簡單的MVC電商網站,MVC電商網站BooksStore第二篇,添加分類導航、加入購物車,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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

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

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

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

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

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

簡介

  上一次我們嘗試了:創建項目架構、創建域模型實體、創建單元測試、創建控制器與視圖、創建分頁和加入樣式,而這一節我們會完成兩個功能,分類導航與購物車。

  主要功能與知識點如下:

    分類、產品瀏覽、購物車、結算、CRUD(增刪改查) 管理、發郵件、分頁、模型綁定、認證過濾器和單元測試等(預計剩余兩篇,預計明天(因為周六不放假)和周三(因為周二不上班)發布)。

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

 

目錄

  • 添加分類導航
  • 加入購物車
  • 創建一個分部視圖 Partial View

 

一、添加分類導航

  上一次我們把網頁劃分成了三個模塊,其中左側欄的部分尚未完成,左側欄擁有將書籍分類展示的功能。

一步步打造簡單的MVC電商網站BooksStore(2)

圖 1

 

  1.回到之前的 BookDetailsViewModels 視圖模型,我們額外再添加一個新的屬性用作分類(CurrentCategory):

 
    /// <summary>
    /// 書籍詳情視圖模型
    /// </summary>
    public class BookDetailsViewModels : PagingInfo
    {
        public IEnumerable<Book> Books { get; set; }

        /// <summary>
        /// 當前分類
        /// </summary>
        public string CurrentCategory { get; set; }
    }
 

 

  2.修改完視圖模型,現在就應該修改對應的 BookController 中的 Details 方法

一步步打造簡單的MVC電商網站BooksStore(2)

 
        /// <summary>
        /// 詳情
        /// </summary>
        /// <param name="category">分類</param>
        /// <param name="pageIndex">頁碼</param>
        /// <returns></returns>
        public ActionResult Details(string category, int pageIndex = 1)
        {
            var model = new BookDetailsViewModels
            {
                Books =
                    _bookRepository.Books.Where(x => category == null || x.Category == category)
                        .OrderBy(x => x.Id)
                        .Skip((pageIndex - 1) * PageSize)
                        .Take(PageSize),
                CurrentCategory = category,
                PageSize = PageSize,
                PageIndex = pageIndex,
                TotalItems = _bookRepository.Books.Count(x => category == null || x.Category == category)
            };

            return View(model);
        }
 
一步步打造簡單的MVC電商網站BooksStore(2)
namespace Wen.BooksStore.WebUI.Controllers
{
    public class BookController : Controller
    {
        private readonly IBookRepository _bookRepository;
        public int PageSize = 5;

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

        /// <summary>
        /// 詳情
        /// </summary>
        /// <param name="category">分類</param>
        /// <param name="pageIndex">頁碼</param>
        /// <returns></returns>
        public ActionResult Details(string category, int pageIndex = 1)
        {
            var model = new BookDetailsViewModels
            {
                Books =
                    _bookRepository.Books.Where(x => category == null || x.Category == category)
                        .OrderBy(x => x.Id)
                        .Skip((pageIndex - 1) * PageSize)
                        .Take(PageSize),
                CurrentCategory = category,
                PageSize = PageSize,
                PageIndex = pageIndex,
                TotalItems = _bookRepository.Books.Count(x => category == null || x.Category == category)
            };

            return View(model);
        }
    }
}
BookController.cs

  

  參數增加了一個 category,用于獲取分類的字符串,對應 Books 中的屬性的賦值語句改為 _bookRepository.Books.Where(x => category == null || x.Category == category),這里的 Lambda 表達式 x => category == null || x.Category == category 的意思是,分類字符串為空就取庫中所有的 Book 實體,不為空時根據分類進行對集合進行篩選過濾。

  還要對屬性 CurrentCategory 進行賦值。

  別忘了,因為分頁是根據 TotalItems 屬性進行的,所以還要修改地方 _bookRepository.Books.Count(x => category == null || x.Category == category),通過 LINQ 統計不同分類情況的個數。

 

  3.該控制器對應的 Details.cshtml 中的分頁輔助器也需要修改,添加新的路由參數:

<div class="pager">
    @Html.PageLinks(Model, x => Url.Action("Details", new { pageIndex = x, category = Model.CurrentCategory }))
</div>
一步步打造簡單的MVC電商網站BooksStore(2)
 1 @model Wen.BooksStore.WebUI.Models.BookDetailsViewModels
 2 
 3 @{
 4     ViewBag.Title = "Books";
 5 }
 6 
 7 @foreach (var item in Model.Books)
 8 {
 9     <div class="item">
10         <h3>@item.Name</h3>
11         @item.Description
12         <h4>@item.Price.ToString("C")</h4>
13         <br />
14         <hr />
15     </div>
16 }
17 
18 <div class="pager">
19     @Html.PageLinks(Model, x => Url.Action("Details", new { pageIndex = x, category = Model.CurrentCategory }))
20 </div>
Details.cshtml

 

  4.路由區域也應當修改一下

一步步打造簡單的MVC電商網站BooksStore(2)
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}",
                defaults: new { controller = "Book", action = "Details" }
            );

            routes.MapRoute(
                name: null,
                url: "{controller}/{action}/{category}",
                defaults: new { controller = "Book", action = "Details" }
            );

            routes.MapRoute(
                name: null,
                url: "{controller}/{action}/{category}/{pageIndex}",
                defaults: new { controller = "Book", action = "Details", pageIndex = UrlParameter.Optional }
            );
        }
RouteConfig.cs

 

  5.現在新建一個名為 NavController 的控制器,并添加一個名為 Sidebar 的方法,專門用于渲染左側邊欄。

一步步打造簡單的MVC電商網站BooksStore(2)

  不過返回的 View 視圖類型變成 PartialView 分部視圖類型:

 
        public PartialViewResult Sidebar(string category = null)
        {
            var categories = _bookRepository.Books.Select(x => x.Category).Distinct().OrderBy(x => x);
            return PartialView(categories);
        }
 

  在方法體在右鍵,添加一個視圖,勾上創建分部視圖。

一步步打造簡單的MVC電商網站BooksStore(2)

  Sidebar.cshtml 修改為:

 
@model IEnumerable<string>

<ul>
    <li>@Html.ActionLink("所有分類", "Details", "Book")</li>
    @foreach (var item in Model)
    {
        <li>@Html.RouteLink(item, new { controller = "Book", action = "Details", category = item, pageIndex = 1 }, new { @class = item == ViewBag.CurrentCategory ? "selected" : null })</li>
    }
</ul>
 

  

  MVC 框架具有一種叫作“子動作(Child Action)”的概念,可以適用于重用導航控件之類的東西,使用類似 RenderAction() 的方法,在當前的視圖中輸出指定的動作方法。

  因為需要在父視圖中呈現另一個 Action 中的分部視圖,所以原來的 _Layout.cshtml 布局頁修改如下:

一步步打造簡單的MVC電商網站BooksStore(2)

 

  現在,啟動的結果應該和圖 1 是一樣的,嘗試點擊左側邊欄的分類,觀察主區域的變化情況。

 

二、加入購物車

一步步打造簡單的MVC電商網站BooksStore(2)

 圖 2

  界面的大體功能如圖 2,在每本圖書的區域新增一個鏈接(添加到購物車),會跳轉到一個新的頁面,顯示購物車的詳細信息 - 購物清單,也可以通過“結算”鏈接跳轉到一個新的頁面。

  

  購物車是應用程序業務域的一部分,因此,購物車實體應該為域模型。

一步步打造簡單的MVC電商網站BooksStore(2)

  1.添加兩個類:

  Cart.cs 有添加、移除、清空和統計功能:

 
    /// <summary>
    /// 購物車
    /// </summary>
    public class Cart
    {
        private readonly List<CartItem> _cartItems = new List<CartItem>();

        /// <summary>
        /// 獲取購物車的所有項目
        /// </summary>
        public IList<CartItem> GetCartItems => _cartItems;

        /// <summary>
        /// 添加書模型
        /// </summary>
        /// <param name="book"></param>
        /// <param name="quantity"></param>
        public void AddBook(Book book, int quantity)
        {
            if (_cartItems.Count == 0)
            {
                _cartItems.Add(new CartItem() { Book = book, Quantity = quantity });
                return;
            }

            var model = _cartItems.FirstOrDefault(x => x.Book.Id == book.Id);
            if (model == null)
            {
                _cartItems.Add(new CartItem() { Book = book, Quantity = quantity });
                return;
            }

            model.Quantity += quantity;
        }

        /// <summary>
        /// 移除書模型
        /// </summary>
        /// <param name="book"></param>
        public void RemoveBook(Book book)
        {
            var model = _cartItems.FirstOrDefault(x => x.Book.Id == book.Id);
            if (model == null)
            {
                return;
            }

            _cartItems.RemoveAll(x => x.Book.Id == book.Id);
        }

        /// <summary>
        /// 清空購物車
        /// </summary>
        public void Clear()
        {
            _cartItems.Clear();
        }

        /// <summary>
        /// 統計總額
        /// </summary>
        /// <returns></returns>
        public decimal ComputeTotalValue()
        {
            return _cartItems.Sum(x => x.Book.Price * x.Quantity);
        }
    }
 

  CartItem.cs 表示購物車中的每一項:

 
    /// <summary>
    /// 購物車項
    /// </summary>
    public class CartItem
    {
        /// <summary>
        ////// </summary>
        public Book Book { get; set; }

        /// <summary>
        /// 數量
        /// </summary>
        public int Quantity { get; set; }
    }
 

 

  2.修改一下之前的 Details.cshtml,增加“添加到購物車”的按鈕:

 
@model Wen.BooksStore.WebUI.Models.BookDetailsViewModels

@{
    ViewBag.Title = "Books";
}

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

        @using (Html.BeginForm("AddToCart", "Cart"))
        {
            var id = item.Id;
            @Html.HiddenFor(x => id);
            @Html.Hidden("returnUrl", Request.Url.PathAndQuery)

            <input type="submit" value="+ 添加到購物車" />
        }

        <br />
        <hr />
    </div>
}

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

 

  【備注】@Html.BeginForm() 方法默認會創建一個 Post 請求方法的表單,為什么不直接使用 Get 請求呢,HTTP 規范要求,會引起數據變化時不要使用 Get 請求,將產品添加到一個購物車明顯會出現新的數據變化,所以,這種情形不應該使用 Get 請求,直接顯示頁面或者列表數據,這種請求才應該使用 Get。

 

  3.先修改下 css 中的樣式

一步步打造簡單的MVC電商網站BooksStore(2)
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;
        }

.item input {
    float: right;
    color: White;
    background-color: green;
}

.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;
    }
Site.css

 

  4.再添加一個 CartController

一步步打造簡單的MVC電商網站BooksStore(2)

 
    /// <summary>
    /// 購物車
    /// </summary>
    public class CartController : Controller
    {
        private readonly IBookRepository _bookRepository;

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

        /// <summary>
        /// 首頁
        /// </summary>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public ViewResult Index(string returnUrl)
        {
            return View(new CartIndexViewModel()
            {
                Cart = GetCart(),
                ReturnUrl = returnUrl
            });
        }

        /// <summary>
        /// 添加到購物車
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public RedirectToRouteResult AddToCart(int id, string returnUrl)
        {
            var book = _bookRepository.Books.FirstOrDefault(x => x.Id == id);

            if (book != null)
            {
                GetCart().AddBook(book, 1);
            }

            return RedirectToAction("Index", new { returnUrl });
        }

        /// <summary>
        /// 從購物車移除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public RedirectToRouteResult RemoveFromCart(int id, string returnUrl)
        {
            var book = _bookRepository.Books.FirstOrDefault(x => x.Id == id);

            if (book != null)
            {
                GetCart().RemoveBook(book);
            }

            return RedirectToAction("Index", new { returnUrl });
        }

        /// <summary>
        /// 獲取購物車
        /// </summary>
        /// <returns></returns>
        private Cart GetCart()
        {
            var cart = (Cart)Session["Cart"];
            if (cart != null) return cart;

            cart = new Cart();
            Session["Cart"] = cart;

            return cart;
        }
    }
 

  【備注】這里的購物車是通過 Session 會話狀態進行保存用戶的 Cart 對象。當會話過期(典型的情況是用戶很長時間沒有對服務器發起任何請求),與該會話關聯的數據就會被刪除,這就意味著不需要對 Cart 對象進行生命周期的管理。

  【備注】RedirectToAction() 方法:將一個 HTTP 重定向的指令發給客戶端瀏覽器,要求瀏覽器請求一個新的 Url。

 

  5.在 Index 方法中選擇右鍵新建視圖,專門用于顯示購物清單:

一步步打造簡單的MVC電商網站BooksStore(2)

  Index.cshtml 中的代碼:

 
@model Wen.BooksStore.WebUI.Models.CartIndexViewModel

<h2>我的購物車</h2>

<table class="table">
    <thead>
        <tr>
            <th>書名</th>
            <th>價格</th>
            <th>數量</th>
            <th>總計</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Cart.GetCartItems)
        {
            <tr>
                <td>@item.Book.Name</td>
                <td>@item.Book.Price</td>
                <td>@item.Quantity</td>
                <td>@((item.Book.Price * item.Quantity).ToString("C"))</td>
            </tr>
        }
        <tr>
            <td> </td>
            <td> </td>
            <td>總計:</td>
            <td>@Model.Cart.ComputeTotalValue().ToString("C")</td>
        </tr>
    </tbody>

</table>

<p>
    <a href="@Model.ReturnUrl">繼續購物</a>
</p>
 

 

  我想,這一定是一個令人激動的時刻,因為我們已經完成了這個基本的添加到購物車的功能。

一步步打造簡單的MVC電商網站BooksStore(2)

 

三、創建一個分部視圖 Partial View

  分部視圖,是嵌入在另一個視圖中的一個內容片段,并且可以跨視圖重用,這有助于減少重復,尤其需要在多個地方需要重復使用相同的數據時。

一步步打造簡單的MVC電商網站BooksStore(2)

  在 Shared 內部新建一個名為 _BookSummary.cshtml 的視圖,并且把之前 Details.cshtml 的代碼進行整理。

一步步打造簡單的MVC電商網站BooksStore(2)

 

  修改后的兩個視圖:

  Details.cshtml

 
@model Wen.BooksStore.WebUI.Models.BookDetailsViewModels

@{
    ViewBag.Title = "Books";
}

@foreach (var item in Model.Books)
{
    Html.RenderPartial("_BookSummary", item);
}

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

 

  _BookSummary.cshtml

 
@model Wen.BooksStore.Domain.Entities.Book

<div class="item">
    <h3>@Model.Name</h3>
    @Model.Description
    <h4>@Model.Price.ToString("C")</h4>

    @using (Html.BeginForm("AddToCart", "Cart"))
    {
        var id = Model.Id;
        @Html.HiddenFor(x => id);
        @Html.Hidden("returnUrl", Request.Url.PathAndQuery)

        <input type="submit" value="+ 添加到購物車" />
    }

    <br />
    <hr />
</div>
 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/liqingwen/p/6647538.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91精品国产乱码久久桃 | 午夜天堂在线视频 | 午夜a狂野欧美一区二区 | 久久亚洲精品久久国产一区二区 | 九九热色 | 最近日本电影hd免费观看 | 日韩黄在线| 亚洲导航深夜福利涩涩屋 | 在线91视频 | 毛片免费在线 | 国产精品视频一区二区三区四区五区 | 欧美一级特黄aaaaaaa什 | 男人久久天堂 | h色在线观看 | 久久久久久久久久美女 | 日韩av电影免费看 | 国产精品一区二区三区在线 | 久草中文网 | 色综合久久久久久久久久久 | 97精品国产高清在线看入口 | 女18一级大黄毛片免费女人 | 欧美日韩国产一区二区三区在线观看 | 成人偷拍片视频在线观看 | 免费一级欧美在线观看视频 | 国产羞羞视频在线观看 | 亚洲乱操| 成年人视频在线免费播放 | 91九色丨porny丨国产jk | 91成| 日韩av电影在线观看 | 国产亚洲精彩视频 | 久久久久久久久亚洲精品 | 香蕉在线看| 超级av在线 | 黄色小视频在线免费看 | 色播视频在线播放 | 视频一区 中文字幕 | 日韩在线播放一区二区 | 亚洲网站免费看 | 在线看一区二区三区 | 国产亚洲精彩视频 |