ModelMetadata系列的結束了,從本篇開始就進入Model綁定部分了,這個系列閱讀過後你會對Model綁定有個比較清楚的了解, 本篇對于Model綁定器的最基礎的應用作個簡單的示例展示,目的在于讓大家事先了解一下Model綁定器是什麼樣的便于後續篇幅的了解。
IModelBinder、自定義Model綁定器簡單實作
Model綁定器在MVC架構中的位置
MVC中的預設Model綁定器生成過程
IModelBinderProvider的簡單應用
IValueProvider在MVC架構中生成的位置以及過程
IValueProvider的應用場景
IValueProvider的實作之NameValueCollectionValueProvider
Model綁定器在前面的篇幅示例中也有涉及到,在本篇中重新講一下,看過前面篇幅的朋友可以大概的浏覽一下本篇,然後跳至下一篇了。
對于Model綁定器系統提供了一個預設的綁定器DefaultModelBinder類型,而它實作了IModelBinder接口,我們來看一下IModelBinder接口的定義,代碼1-1.
代碼1-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<code>public</code> <code>interface</code> <code>IModelBinder</code>
<code> </code><code>{</code>
<code> </code><code>// 摘要:</code>
<code> </code><code>// 使用指定的控制器上下文和綁定上下文将模型綁定到一個值。</code>
<code> </code><code>//</code>
<code> </code><code>// 參數:</code>
<code> </code><code>// controllerContext:</code>
<code> </code><code>// 控制器上下文。</code>
<code> </code><code>// bindingContext:</code>
<code> </code><code>// 綁定上下文。</code>
<code> </code><code>// 傳回結果:</code>
<code> </code><code>// 綁定值。</code>
<code> </code><code>object</code> <code>BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);</code>
<code> </code><code>}</code>
看到代碼1-1中,IModelBinder接口中定義了一個BindModel()方法,并且有兩個參數,通過系統提供給我們的注釋了解到,一個是控制器上下文對象,還有一個是綁定器上下文對象,控制器上下文對象的意思就是在目前控制器所執行範圍内的所有基礎資訊都包含在其中,同理綁定上下文也是。後續的篇幅會對這一系列的上下文對象作詳細的介紹,這裡就帶過了。
現在我們來實作IModelBinder接口定義個自己的Model綁定器,當然了也可以繼承自DefaultModelBinder類型重寫一下BindModel()方法。我們來看一下我們的自定義實作,代碼1-2.
代碼1-2
17
18
19
20
21
22
23
<code>using</code> <code>System.Web.Mvc;</code>
<code>using</code> <code>ConsoleApplication2;</code>
<code>namespace</code> <code>MvcApplication.Binders</code>
<code>{</code>
<code> </code><code>public</code> <code>class</code> <code>MyCustomModelBinder:IModelBinder</code>
<code> </code><code>public</code> <code>object</code> <code>BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)</code>
<code> </code><code>{</code>
<code> </code><code>return</code> <code>new</code> <code>Customer()</code>
<code> </code><code>{</code>
<code> </code><code>CustomerID = </code><code>"010"</code><code>,</code>
<code> </code><code>Name = </code><code>"測試人員"</code><code>,</code>
<code> </code><code>RegistrationDate = DateTime.Now,</code>
<code> </code><code>Address = </code><code>new</code> <code>Address()</code>
<code> </code><code>{</code>
<code> </code><code>AddressName = </code><code>"天空之城"</code>
<code> </code><code>}</code>
<code> </code><code>};</code>
<code> </code><code>}</code>
<code>}</code>
對于ConsoleApplication2命名空間的引用是因為ViewModel被定義在了那裡,也就是代碼1-2中BindModel()方法所要傳回的類型,在代碼1-2中我們隻是簡單的執行個體化了一個ViewModel(Customer類型),實際可以做的操作非常多。我們再看一下ViewModel的定義,代碼1-3。
代碼1-3
<code>public</code> <code>class</code> <code>Customer</code>
<code> </code><code>[HiddenInput(DisplayValue=</code><code>false</code><code>)]</code>
<code> </code><code>public</code> <code>string</code> <code>CustomerID { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>[Display(Name=</code><code>"姓名"</code><code>)]</code>
<code> </code><code>[UIHint(</code><code>"Password"</code><code>)]</code>
<code> </code><code>public</code> <code>string</code> <code>Name { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>[DataType(DataType.Date)]</code>
<code> </code><code>[Display(Name=</code><code>"注冊日期"</code><code>)]</code>
<code> </code><code>public</code> <code>DateTime RegistrationDate{ </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>[UIHint(</code><code>"Address"</code><code>)]</code>
<code> </code><code>public</code> <code>Address Address { </code><code>get</code><code>; </code><code>set</code><code>; } </code>
<code> </code><code>public</code> <code>class</code> <code>Address</code>
<code> </code><code>[Display(Name=</code><code>"位址名稱"</code><code>)]</code>
<code> </code><code>[MyCustomMetadataAware]</code>
<code> </code><code>public</code> <code>string</code> <code>AddressName { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
代碼1-3就是ViewModel的定義了,其中包含的一些資訊有不清楚的可以在看完本篇後去看ASP.NET MVC Model中繼資料系列。
現在我們看一下控制器方法的定義,代碼1-4.
代碼1-4
<code> </code><code>public</code> <code>ViewResult Show(Customer customer)</code>
<code> </code><code>return</code> <code>View(customer);</code>
為什麼ViewModel要以作為控制器方法參數的方式來進行Model綁定呢?這個疑問在下篇中會解決。
看一下代碼1-5,作為Show方法對應視圖的代碼:
代碼1-5
<code>@model ConsoleApplication2.Customer</code>
<code>@{</code>
<code> </code><code>ViewBag.Title = "Show";</code>
<code><</code><code>h2</code><code>>Show</</code><code>h2</code><code>></code>
<code><</code><code>p</code><code>>@Html.EditorForModel()</</code><code>p</code><code>></code>
<code><</code><code>p</code><code>>@Html.EditorFor(m=>Model.Address)</</code><code>p</code><code>></code>
這樣就完成了基礎的工作了,不過還是運作不了,因為我們自定義的Model綁定器還沒有定義到系統中,在項目的Global.asax檔案中的MvcApplication類型的Application_Start()方法中添加如代碼1-6。
代碼1-6
<code>ModelBinders.Binders.Add(</code><code>typeof</code><code>(Customer), </code><code>new</code> <code>Binders.MyCustomModelBinder());</code>
當然了也不限于在這裡添加,隻要在授權過濾器執行之前的任何一個地方都行,因為在授權過濾器執行過後便會對Model綁定器進行生成了,下篇會有講解。在這裡添加隻不過這裡是MVC最先執行的地方。現在我們運作檢視結果了。
圖1

本文轉自jinyuan0829 51CTO部落格,原文連結:http://blog.51cto.com/jinyuan/1431401,如需轉載請自行聯系原作者