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