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

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

前面几话都讲的一些有关MVC相关东西,从这话开始应用实战的项目开始。

实战一个简单的购物流程的项目吧!

首先创建一个空白的解决方案,如下图1.

图1.我们预计创建3个模块,一个模块包含我们的域模型(DoMain),一个模块包含我的MVC Web应用程序,还有一个单元测试的模块。

我们的域模型(DoMain)是一个类库项目,然后是一个Asp.Net MVC3 的Web应用程序(Razor引擎)项目,然后添加一个测试项目进来,添加测试项目如下图2.

图2.当我们创建好我们的域模型(DoMain)类库项目和测试项目(类库项目),VS会自动创建一个Class1.cs的文件和UnitTest1.cs的文件,这个对我们来说没有多大的用处,可以直接干掉。之后我们的行么如下图3.

图3.下一步就是添加项目引用,可项目需要用到包(扩展工具/第三方插件),我们项目具体要用到的第三方插件如下:

具体项目第三插件名称SportsStore.DomainNinjectSportsStore.UINinjectSportsStore.DomainMoqSportsStore.UIMoq             

可以在VS里面的"程序包控制管理"用下面的命令导入第三方插件包,命令如下:

Install-Package Ninject -Project SportsStore.WebUI 
Install-Package Ninject -Project SportsStore.Domain 
Install-Package Moq -Project SportsStore.WebUI 
Install-Package Moq -Project SportsStore.Domain

也可以在相关项目上右键,使用NuGet程序包管理一个一个导入,方法根据自己所好,不在啰嗦!

然后就是我们项目的依赖关系,如下表所示:

具体项目依赖项目SportsStore.Domain无SportsStore.UISportsStore.DomainSportsStore.UnitTests

SportsStore.Domain

SportsStore.UI

因为我们将使用Ninject创建我们的MVC应用程序控制器和处理DI,所以我们需要创建一个新的类更改配置。在SportsStore.UI应用程序里创建一个文件夹(命名"Infrastructure")然后在改文件里创建一个类叫NinjectControllerFactory,它的代码如下:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using Ninject;using System.Web.Routing;using Moq;using SportsStore.Domain.Abstract;using SportsStore.Domain.Entities;namespace SportsStore.WebUI.Infrastructure{    public class NinjectControllerFactory : DefaultControllerFactory    {        private IKernel ninjectKernel;        public NinjectControllerFactory()         {            this.ninjectKernel = new StandardKernel();            AddBindings();        }        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)        {            return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType);        }        private void AddBindings()        {            //绑定额外数据        }    }}
复制代码

我们需要注册NinjectControllerFactory到MVC框架,所以我们也需要在Global.asax.cs里给它注册进去,具体代码如下:

复制代码
     protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            RegisterGlobalFilters(GlobalFilters.Filters);            RegisterRoutes(RouteTable.Routes);            //注册路由            ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());        }
复制代码

我们可以试着启动跑下我的MVC Web项目,结果如下图4.

图4.如果真出现这个错误页面也是预计必然的结果,接下来的任务就是让这个页面消失吧!

从我们的域模型(DoMain)开始吧!既然我们搞的是一个购物流程的项目,那我们肯定需要商品才能购物,那就在域模型(Domain)里创建一个文件夹(命名"Entities")放相应的模型在该文件夹来创建一个Product类吧!Product类的代码如下:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace SportsStore.Domain.Entities{    public class Product : Object    {        public int ProductID { get; set; }        public string Name { get; set; }        public string Description { get; set; }        public decimal Price { get; set; }        public string Category { get; set; }    }}
复制代码

接下来创建一个抽象存储库,我们知道我们用一些方法可以是Prodcut和数据交互,这里我们使用存储库模式,我们不需要担心他是如何去实现,所以在域模型(DoMain)项目里建立一个文件夹(命名"Abstract")在该文件里创建一个接口"IProductRepository",它的代码如下:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using SportsStore.Domain.Entities;namespace SportsStore.Domain.Abstract{    public interface IProductRepository    {        IQueryable<Product> Products { get; }    }}
复制代码

这个接口使用这个IQueryable < T >可以获取Product对象,它没有说任何关于如何或数据存储在哪里或者它将如何被检索。一个类,它使用IProductRepository接口就可以获得Product对象,但是不需要知道任何关于它们来自于哪儿,或者他们如何将被交付到那儿,这是最基本的存储库的模式。

然后我们使用模拟库,因为我们一定定义了一个接口那么我接着就实现它,让他跟数据交互,我们模拟一下实现IProductRepository接口,代码如下:

复制代码
        private void AddBindings()        {            //绑定额外数据            //模拟IProductRepository实现            Mock<IProductRepository> mock = new Mock<IProductRepository>();            mock.Setup(h => h.Products).Returns(new List<Product>{            new Product {Name="FootBall",Price=25},            new Product {Name="Surf Board",Price=179},            new Product {Name="Running shoes",Price=95}            }.AsQueryable());            this.ninjectKernel.Bind<IProductRepository>().ToConstant(mock.Object);        }
复制代码

准备工作的差不多了我们需要要能展现的东西出来才不算前功尽弃,我们要展示出我们的商品,首先要来创建相应的控制器(命名"ProductController"),代码如下:

复制代码
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 ProductController : Controller    {        private IProductRepository repository;        public ProductController(IProductRepository productReposittory)         {            this.repository = productReposittory;        }    }}
复制代码

这个只不过是一个的空的控制器,我们创建了一个构造函数,该函数接收IProductRepository来的参数,这里也就方便Ninject在Product对象实例化的时候的注入(构造注入)。然后我需要返回一个视图展示出来,所以修改ProductController控制器如下:

复制代码
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 ProductController : Controller    {        private IProductRepository repository;        public ProductController(IProductRepository productReposittory)         {            this.repository = productReposittory;        }        //返回一个视图        public ViewResult List()        {            return this.View(this.repository.Products);        }    }}
复制代码

接下来,需要添加一个视图(View),我们需要创建一个强类型视图,如下图5.

图5.当然在我们选择模型类的时候,下拉框并不能找到IEnumerable<SportsStore.Domain.Entities.Product>,因为他不会包含枚举的域模型(DoMain)对象,所以需要我们手动输入。

IEnumerable<Product>意味着我们可以创建一个列表,现在就用犀利Razor引擎来搞这个页面,List.cshtml页面代码如下:

复制代码
@model IEnumerable<SportsStore.Domain.Entities.Product>@{    ViewBag.Title = "Product List";}@foreach (var Product in Model){    <div class="item">    <h3>@Product.Name</h3>    @Product.Description    <h4>@Product.Price.ToString("C")</h4>    </div>}
复制代码

说明:@Product.Price.ToString("C"),ToString("C")根据你的服务器将数字转换为相应的货币。

然后我们需要修改一下默认的路由,具体的修改如下:

复制代码
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using System.Web.Routing;using SportsStore.WebUI.Infrastructure;namespace SportsStore.WebUI{    // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,    // 请访问 http://go.microsoft.com/?LinkId=9394801    public class MvcApplication : System.Web.HttpApplication    {        public static void RegisterGlobalFilters(GlobalFilterCollection filters)        {            filters.Add(new HandleErrorAttribute());        }        public static void RegisterRoutes(RouteCollection routes)        {            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");            routes.MapRoute(                "Default", // 路由名称                "{controller}/{action}/{id}", // 带有参数的 URL                new { controller = "Product", action = "List", id = UrlParameter.Optional } // 参数默认值            );        }        protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            RegisterGlobalFilters(GlobalFilters.Filters);            RegisterRoutes(RouteTable.Routes);            //注册路由            ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());        }    }}
复制代码

注明:修改就是上面代码红色部分里标识为蓝色的控制器名称和相应方法(Action)名称。

接下来,在跑下我们的MVC Web应用程序,运行结果如下图6所示.

图6.可以看到我们已经消灭之前的黄页了,项目开始就先搞怎么些东西,后续继续完善。