您的位置:首页 > 编程语言 > ASP

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

2012-07-04 18:00 471 查看
前面几话都讲的一些有关MVC相关东西,从这话开始应用实战的项目开始。

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

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


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

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


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


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

具体项目第三插件名称
SportsStore.DomainNinject
SportsStore.UINinject
SportsStore.DomainMoq
SportsStore.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.Domain
SportsStore.UnitTestsSportsStore.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.可以看到我们已经消灭之前的黄页了,项目开始就先搞怎么些东西,后续继续完善。要是那里描述有误还请路过的前辈牛人给点指点,这样才能更好的进步,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: