Asp.Net Mvc 3.0【MVC项目实战の三】

来源:互联网 发布:加工中心编程格式要领 编辑:程序博客网 时间:2024/05/21 15:04

我的项目只不过构建了大体的样子,接下来我们需要完成导航部分购物车部分,订单部分等。只有这些模块搞完,我们的购物流程项目才算大体的搞完。接下来,就从我们的导航开始吧!

添加导航

如果在我们的项目应用导航展示给用户,我们应该做一下的事情:

  • 加强我们的模型(ProductsListViewModel),加强之后的模型必须过滤商品的属性。
  • 重构我们的URL,修改我们路由机制。
  • 创建类别列表,显示在网站的侧边栏里。

加强我们的模型(ProductsListViewModel),我们需要把不同类别展示在网站的侧边栏里让用户一目明了。ProductsListViewModel模型修改如下:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Web;using SportsStore.Domain.Entities;namespace SportsStore.WebUI.Models{    public class ProductsListViewModel    {        public IEnumerable<Product> Products { get; set; }        public PagingInfo PagingInfo { get; set; }        //添加CurrentCategory属性        public string CurrentCategory { get; set; }    }}
复制代码

模型(ProductsListViewModel)我们已经添加了属性进来,下来我们需要修改我们的ProductController(控制器)里的List(Action)方法,我们需要在List方法使用我们添加的属性按照分类过滤商品对象。修改ProductContrller如下:

View Code

上面的代码,我们添加了一个新的分类参数,我们做到这里即便我们做了稍微的改变运行一下我们的程序,自己试着拼一个URL分类的字符串。运行如下图1.

图1.可以看出我们拼的字符串可以正确的显示出我们拼的分类列表。但是像Http://localhost:XXXX/?category=people的连接我相信大家都是不喜欢的。所以我们要从新定义一套路由机制来改变这种URL访问的方式。然后在我们的Global.asax文件中配置一下几条路由,代码如下:

View Code

总结一下我们配置的这些路由机制,如下表:

URL引导/展示列表第一页的所有商品信息/page2展示列表指定页面(这里指第2页)的商品信息/Soccer展示特定分类第一页的商品信息/Soccer/Page2展示特定分类页特定页面(这里指第二页)的商品信息/Anything/Else调用任何控制器里的的其他方法

 

 

 

 

 Asp.Net路由系统使用在MVC来处理客户端的请求,外来的URL请求要是有符合我们配置的URL,就会访问到我们Web程序相应的页面。在Razor引擎的写法里,大家都应该知道URl.Action方法是最常见的添加外链的方法,那么下来就在我们的List.cshtml商品展示页面添加我们的分类信息,具体代码如下:

复制代码
@model SportsStore.WebUI.Models.ProductsListViewModel@{    ViewBag.Title = "Product List";}@foreach (var Pro in Model.Products){    Html.RenderPartial("ProductSummary", Pro);}<div class="pager">@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { Page = x ,category = Model.CurrentCategory}))</div>
复制代码

接下来我们需要构造一个类别的导航菜单,在我们的MVC Web项目里的Controllers文件夹右键添加"控制器",命名"NavController",然后干掉VS自动创建好的Index 方法(Action),然后定义我们的方法,代码如下:

复制代码
using System.Web.Mvc; namespace SportsStore.WebUI.Controllers {      public class NavController : Controller {        public string Menu() {        return "Hello from NavController";       }    }}
复制代码

我们的Menu方法返回的字符串,但是我们想让我们的类别出现在任何页面,所以我们要配置我们的模版(_Layout.cshtml),使它调用我们的显示导航菜单的方法,所以我们修改我们的Layout.cshtml的代码如下:

复制代码
<!DOCTYPE html><html><head>    <title>@ViewBag.Title</title>    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script></head><body><div id="header"><div class="title">SPOPTS STORE</div></div><div id="categories">@{Html.RenderAction("Menu", "Nav");}</div>    <div id="content">    @RenderBody()    </div></body></html>
复制代码

我们现在已经在模版中给我们的导航菜单分配了一块展示的地方,现在运行一下我们的Mvc Web程序,结果如下图2.

图2.现在我们就可以去实现这个展示导航菜单的位置了,不能让这个展示导航的地方老是显示一句我们测试的字符串,接下来我们就生成我们的导航列表,但是我们有不愿意生成控制器类(NavController)的URL,所以我们将尝试用一个辅助方法来搞View(视图),所以需要Menu Action(方法)是创建一个分裂的列表,修改控制器("NavController")代码如下:

View Code

接下来我们需要创建一个局部视图,为什么是局部视图,因为我们的导航菜单是我们页面整体的一部分,所以我们就用局部视图,在Menu Action(方法)上右键添加视图,具体如下图3。

图3.我们还是创建的强类型视图模型,我们的模型类类型选择的是IEnumerable<string>,创建好我们的局部视图Menu后,修改他的内容如下:

复制代码
@model IEnumerable<string>@{    this.Layout = null; }@Html.ActionLink("Home","List","Product")@foreach (var item in Model){    @Html.RouteLink(item, new { controller = "Product", action = "List", category = item, page = 1 });}
复制代码

首先我们添加一个Home(首页)的连接使用的是ActionLink,这个连接会展示出我们所有商品信息。这种的URL请求机制我们在Global.asax文件中已经配置过来。然后我们使用循环列举了所有的列表使用的RouteLink(这个和ActionLinke类似),但是这个需要我们供给一组类似"名称/值(Name/Value)"对,请求时来从路由配置(具体到路由的东西后续分享)。到这里我们在跑下我们的Web程序看看!如下图4.

图4.哦,我们应该还需要一个"高亮"的效果,就是当我们/用户点击到某个分裂的时候,当前分类应该处于选择状态的时候,有"高亮"效果,我们修改一下我们修改一下我们的Menu Action(方法)及对应的前台代码。

修改Menu Action(方法)具体如下:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using SportsStore.Domain.Abstract;namespace SportsStore.WebUI.Controllers{    public class NavController : Controller    {        private IProductRepository repository;        public NavController(IProductRepository repo)        {            this.repository = repo;        }        public PartialViewResult Menu(string category = null)        {            this.ViewBag.SelectedCategory = category;            IEnumerable<string> categories = this.repository.Products                                                 .Select(h => h.Category)                                                 .Distinct()                                                 .OrderBy(h => h);            return this.PartialView(categories);        }    }}
复制代码

修改页面Menu.cshtml如下(选择类别的高亮实现):

复制代码
@model IEnumerable<string>@{    this.Layout = null; }@Html.ActionLink("Home","List","Product")@foreach (var item in Model){    @Html.RouteLink(item, new { controller = "Product", action = "List", category = item, page = 1 },    new    {        @class = item == this.ViewBag.SelectedCategory ? "selected" : null    });}
复制代码

注:具体实现高亮的地方,代码都表明使用了红色粗体。

接下来运行我们的web程序如下图5.

图5.这里我们的高亮效果已定是OK的了。接下来我们似乎有出现一个新的问题,就是在我们某些类别页面存在分页没有商品的信息,如下图6.

图6.为什么呢!还记得前面我们搞分页的时候,依据的商品的总数量,与分类好无瓜葛,所以导致现在这种局面也是必然。所以当用户点击某些类别的具体某些页面时,没有足够的商品信息展示出来就出现空白页面,接下来就搞这个问题吧!问题的根源弄出来,那么我们是不是应该在商品展示List Action(方法)上动些手脚,让分页的时候把类别也考虑进来,所以修改ListAction(方法)如下:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using SportsStore.Domain.Abstract;using SportsStore.Domain.Concrete;using SportsStore.WebUI.Models;namespace SportsStore.WebUI.Controllers{    public class ProductController : Controller    {        public int PageSize = 4; //设置一页显示多少商品        private IProductRepository repository;        public ProductController(IProductRepository productReposittory)         {            this.repository = productReposittory;        }        //返回一个视图        public ViewResult List(string category, int page = 1)        {            ProductsListViewModel viewModel = new ProductsListViewModel            {                Products = this.repository.Products                                                .Where(h => category == null || h.Category == category)                                                .OrderBy(h => h.ProductID)                                                .Skip((page - 1) * PageSize)                                                .Take(PageSize),                PagingInfo = new PagingInfo                {                    CurrentPage = page,                    ItemsPerPage = PageSize,                    TotalItems = category == null ? this.repository.Products.Count() :                    this.repository.Products.Where(h => h.Category == category).Count()                },                CurrentCategory = category            };            return this.View(viewModel);        }    }}
复制代码

这样修改后,当我们选择某些特定的类别的时候,就返回特定类别的商品的总数,就会正确的分页,避免之前的空白页面了!到时是不是呢,我们还是刚才选择的那个分类运行下我们的web项目,如下图7.

图7.这里已经没有什么在说的了,证明我们的修改是OK的。

接下是相对于之前比较复杂的购物车,说是复杂就复杂,要说不复杂也就不复杂了,直白点"购物车不就那几点事,无非就是计算我们的商品价格,无非就是支付,无非就是跟商品页面的交互,...",我们项目的购物车的流程如下图8.

图8.具体实现购物车的东东后续在继续

原创粉丝点击