第五話 Asp.Net MVC 3.0【MVC實戰項目の一】


前面幾話都講的一些有關MVC相關東西,從這話開始應用實戰的項目開始。

實戰一個簡單的購物流程的項目吧!

首先創建一個空白的解決方案,如下圖1.

圖1.我們預計創建3個模塊,一個模塊包含我們的域模型(DoMain),一個模塊包含我的MVC Web應用程序,還有一個單元測試的模塊。

我們的域模型(DoMain)是一個類庫項目,然后是一個Asp.Net MVC3 的Web應用程序(Razor引擎)項目,然后添加一個測試項目進來,添加測試項目如下圖2.

圖2.當我們創建好我們的域模型(DoMain)類庫項目和測試項目(類庫項目),VS會自動創建一個Class1.cs的文件和UnitTest1.cs的文件,這個對我們來說沒有多大的用處,可以直接干掉。之后我們的行么如下圖3.

圖3.下一步就是添加項目引用,可項目需要用到包(擴展工具/第三方插件),我們項目具體要用到的第三方插件如下:

具體項目 第三插件名稱
SportsStore.Domain Ninject
SportsStore.UI Ninject
SportsStore.Domain Moq
SportsStore.UI Moq             

可以在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.UI SportsStore.Domain
SportsStore.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.可以看到我們已經消滅之前的黃頁了,項目開始就先搞怎么些東西,后續繼續完善。要是那里描述有誤還請路過的前輩牛人給點指點,這樣才能更好的進步,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM