標籤:asp.net asp.net mvc mvc view
ASP.NET MVC 視圖(三)
前言
上篇對於Razor視圖引擎和視圖的類型做了大概的講解,想必大家對視圖的本身也有所瞭解,本篇將利用IoC架構對視圖的實現進行依賴注入,在此過程過會讓大家更瞭解的視圖,最後還會簡單的介紹一下自訂的視圖輔助器是怎麼定義和使用的。
ASP.NET MVC 視圖
l 自訂視圖引擎
l Razor視圖引擎執行過程
l Razor視圖的依賴注入、自訂視圖輔助器
l 分段、分部視圖的使用
l Razor文法、視圖輔助器
Razor視圖的依賴注入
首先我們來看一下要定義實現依賴注入的功能介面規範和預設實現,範例程式碼1-1.
代碼1-1
using System.Web.Mvc;using Ninject; namespace MvcApplication.Models{ public interface IStringManage { MvcHtmlStringCombinationString(string strPar1, string strPar2); } public class DefaultStringManage: IStringManage { public MvcHtmlString CombinationString(string strPar1, stringstrPar2) { returnnew MvcHtmlString(strPar1+ strPar2); } }}
在IStringManage類型中定義了CombinationString()方法,用於將兩個字串類型的數值拼接起來,DefaultStringManage類型就是預設實現了,這裡就不多說了。
下面我們再來定義在編譯時間刻視圖將要實現繼承的類型,範例程式碼1-2
代碼1-2
using System.Web.Mvc;using Ninject; namespace MvcApplication.Models{ public abstract class StringManageView : WebViewPage { [Inject] public IStringManage StringManage { get; set; } }}
這樣的定義起初是不會有什麼問題的,因為cshtml視圖檔案在編譯時間是繼承自WebViewPage類型的,現在我們要讓cshtml視圖所繼承的類型是StringManageView,所以必須讓StringmanageView繼承自WebViewPage,因為WebViewPage是抽象類別型,而我們又不想實現什麼所以要定義為抽象類別型,在StringManageView類型中,我定義了IStringManage類型的屬性StringMange,並且使用IoC架構中的Inject特性來描述它,使的在編譯是可以通過IoC來實現屬性的依賴注入。
下面我們來看一下視圖代碼,這裡的視圖代碼還是引用前面篇幅使用最多的一個樣本,代碼1-3和代碼1-4
代碼1-3
public ActionResultIndex(List<Product>model){ ViewBag.StrPar1 = "Thisis"; ViewBag.StrPar2 = "ViewIoCCase"; returnView(model); }
代碼1-4
@inherits MvcApplication.Models.StringManageView@{ ViewBag.Title = "Index";}<h2> Index</h2>@foreach (varitem in Model){ <h3>ID: @item.ID Name:@item.Name</h3>}<h2>@StringManage.CombinationString(ViewBag.StrPar1,ViewBag.StrPar2)</h2>
控制器方法部分的代碼定義是沒有問題的,在代碼1-4,也就是Index視圖的定義中通過@inherits指令來使視圖檔案在編譯時間繼承自某個類型,以及在下面的使用中用到了StringManage屬性,並且還調用了方法,這裡看起來都沒什麼問題,但是放在這裡用就有問題了,因為上面使用了foreach來遍曆Model,在我們定義StringManageView的時候並沒有對Model的類型做約束什麼的,而控制器方法中也是需要將List<Product>類型傳遞到視圖的,這裡就引起了衝突,圖1.
圖1
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/40/3E/wKiom1POTfTjiK1vAAFnLrzmTGY506.jpg" title="ViewEngine1.png" alt="wKiom1POTfTjiK1vAAFnLrzmTGY506.jpg" />
遇到這種情況我們只需修改一下代碼1-2中的定義,讓Model類型是在編譯時間是可確定的而不是object類型,來看代碼1-5
代碼1-5
public abstract class StringManageView: WebViewPage<dynamic>{ [Inject] public IStringManage StringManage { get; set; }}
對的,讓StringManageView實現泛型的WebViewPage就可以了,上個篇幅中視圖的基類也都是這樣定義的,不是說上面代碼1-2定義的就是錯誤的,定義的沒有錯,只是應用的視圖不合適,因為Index視圖本身需要對Model做一些操作,又不想因為為視圖添加的依賴注入功能而修改所以才會引起的這個錯誤,如果放在普通的視圖裡使用那是沒有問題的。
上面這些都定義好了,下面我們需要實現自訂的IDependencyResolver類型,目的在於綁定我們需要進行依賴注入的功能模組到IoC中,代碼1-6.
代碼1-6
using Ninject;using System.Web.Mvc; namespace MvcApplication.CustomDependencyResolver{ public class NinjectDependencyResolver:IDependencyResolver { privateIKernel Kernel; publicNinjectDependencyResolver() { Kernel = newStandardKernel(); AddBinding(); } privatevoid AddBinding() { Kernel.Bind<Models.IStringManage>().To<Models.DefaultStringManage>(); } public object GetService(TypeserviceType) { returnthis.Kernel.TryGet(serviceType); } public IEnumerable<object>GetServices(Type serviceType) { returnthis.Kernel.GetAll(serviceType); } }}
對於代碼1-6就不作過多的解釋了,在控制器啟用部分都講解過近乎類似的注入封裝類型。
最後我們在Global.asax檔案的Application_Start()方法中,將Model綁定器和NinjectDependencyResolver類型添加中MVC架構中,代碼1-7
代碼1-7
ModelBinders.Binders.Add(typeof(List<Product>),new CustomListModelBinder());DependencyResolver.SetResolver(newCustomDependencyResolver.NinjectDependencyResolver());
最後看下結果,圖2.
圖2
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/40/3E/wKioL1POTzagPr9mAADcTdSZOnk179.jpg" title="ViewEngine2.png" alt="wKioL1POTzagPr9mAADcTdSZOnk179.jpg" />
自訂視圖輔助器
實際上自訂視圖輔助器就是擴充方法的定義,首先我們來看定義,實現的功能同代碼1-1相同,代碼2-1
using System.Web.Mvc; namespace MvcApplication.CustomHtmlHelper{ public static class MyCustomHtmlHelper { public static MvcHtmlStringCombinationString(this HtmlHelperhtmlHelper, string strPar1, string strPar2) { returnnew MvcHtmlString(strPar1+ strPar2); } }}
代碼2-1這樣的一個類型也就是自訂視圖輔助器了,當然了這隻是一個簡單的樣本,現在我們需要把它在視圖中使用起來,我們得先把這個自訂的視圖輔助器所在的命名空間添加到Views檔案中的Web.Config中,代碼2-2.
代碼2-2
<system.web.webPages.razor> <hostfactoryType="System.Web.Mvc.MvcWebRazorHostFactory,System.Web.Mvc, Version=3.0.0.0, Culture=neutral,PublicKeyToken=31BF3856AD364E35" /> <pagespageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <addnamespace="System.Web.Mvc" /> <addnamespace="System.Web.Mvc.Ajax" /> <addnamespace="System.Web.Mvc.Html" /> <addnamespace="System.Web.Routing" /> <addnamespace="MvcApplication.CustomHtmlHelper"/> </namespaces> </pages> </system.web.webPages.razor>
然後是在視圖中引用擴充方法所處的命名空間,這樣配置過後就可以在視圖用運用了我們剛剛自訂的視圖輔助器了,代碼2-3.
代碼2-3
@inherits MvcApplication.Models.StringManageView@usingMvcApplication.CustomHtmlHelper@{ ViewBag.Title = "Index";}<h2> Index</h2>@foreach (varitem in Model){ <h3>ID: @item.ID Name:@item.Name</h3>}<h2>@StringManage.CombinationString(ViewBag.StrPar1,ViewBag.StrPar2)</h2>@Html.CombinationString("This is a ","Case")
最後我們看一下結果3.
圖3
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M01/40/3F/wKiom1POTkuzE0MoAADpgwWbUWU099.jpg" title="ViewEngine3.png" alt="wKiom1POTkuzE0MoAADpgwWbUWU099.jpg" />
本文出自 “金源” 部落格,請務必保留此出處http://jinyuan.blog.51cto.com/8854733/1441508
ASP.NET MVC 視圖(三)