亚洲AV综合AV国产AV百度云-在线观看成人永久免费网站-人妻精品无码一区二区三区-亚洲AV无码理论亚洲毛片

Micronet微網(wǎng)

網(wǎng)絡(luò)商學(xué)院  ESCHOOL
文章分類
ASP.NET MVC模型綁定的6個(gè)建議
更新時(shí)間:2011-11-04
點(diǎn)擊率:858

ASP.NET MVC中的Model Binding使用起來(lái)非常簡(jiǎn)單。你的Action方法需要數(shù)據(jù),在傳入的HTTP請(qǐng)求中攜帶著你需要的數(shù)據(jù),數(shù)據(jù)可以在請(qǐng)求的表單數(shù)據(jù)中,還可能在你的URL地址本身中。通過(guò)DefaultModelBinder,可以神奇地將表單中的數(shù)據(jù)和路由中的數(shù)據(jù)轉(zhuǎn)換到對(duì)象中。Model Binder使得你的控制器代碼可以干凈地從請(qǐng)求以及關(guān)聯(lián)的環(huán)境中分離出來(lái)。

這里有一些關(guān)于在MVC項(xiàng)目中更好使用Model Binding的建議。

Tip#1:最好使用Model Binding而不是Request.Form

如果你的Action像下面這樣:

  1. [AcceptVerbs(HttpVerbs.Post)]   
  2.  
  3. public ActionResult Create()   
  4.  
  5. {   
  6.  
  7.     Recipe recipe = new Recipe();   
  8.  
  9.     recipe.Name = Request.Form["Name"];   
  10.  
  11.         
  12.  
  13.     // ...   
  14.  
  15.         
  16.  
  17.     return View();   
  18.  
  19. }   

就不對(duì)了。這些屬性使得你的Action很難讀而且更難以測(cè)試,Model Binder可以幫你從Request和HttpContext中擺脫出來(lái)。比如,你可以使用FormCollection類型的參數(shù)來(lái)代替上面的代碼:

  1. public ActionResult Create(FormCollection values)   
  2.  
  3. {   
  4.  
  5.     Recipe recipe = new Recipe();   
  6.  
  7.     recipe.Name = values["Name"];         
  8.  
  9.                 
  10.  
  11.     // ...   
  12.  
  13.                 
  14.  
  15.     return View();   
  16.  
  17. }   

使用FormCollection你可以不必再深入到Request對(duì)象,這樣,有時(shí)候你就可以使用低層次的控制了。但是,如果你的數(shù)據(jù)來(lái)自Request.Form,或者URL請(qǐng)求參數(shù),你可以通過(guò)Model Binding來(lái)完成它的魔術(shù)。

  1. [AcceptVerbs(HttpVerbs.Post)]   
  2.  
  3. public ActionResult Create(Recipe newRecipe)   
  4.  
  5. {               
  6.  
  7.     // ...   
  8.  
  9.         
  10.  
  11.     return View();   
  12.  
  13. }   

在這個(gè)例子中,Model Binder將會(huì)幫你創(chuàng)建newRecipe對(duì)象,并且使用從Request中獲得獲得的數(shù)據(jù)來(lái)填充它,真的是魔術(shù)。有許多的途徑允許你定制綁定的處理過(guò)程,使用白名單,黑名單,前綴,以及接口,更多的控制還允許你通過(guò)UpdateModel和TryUpdateModel方法進(jìn)行,只是要注意無(wú)意的綁定?匆豢碕ustin Etheredge的文章Think Before You Bind.

Tip#2定制Model Binder

在MVC中,Model Binding也是一個(gè)擴(kuò)展點(diǎn)。如果默認(rèn)的綁定不合適的話,你可以提供一個(gè)自定義的Model Binder,實(shí)現(xiàn)自定義的Model Binder你需要實(shí)現(xiàn)接口IModelBinder,這是僅有的一個(gè)方法,有多難嗎?

  1. public interface IModelBinder   
  2.  
  3. {   
  4.  
  5.     object BindModel(ControllerContext controllerContext,   
  6.  
  7.                       ModelBindingContext bindingContext);   
  8.  
  9. }   

一旦你進(jìn)入Model Binding,實(shí)際上,你將會(huì)發(fā)現(xiàn)這個(gè)簡(jiǎn)單的IModelBinder接口并沒(méi)有完全描述在框架中的默認(rèn)契約和負(fù)作用。如果你退回一步看一看,就會(huì)發(fā)現(xiàn)Model Binder,ModelState以及HtmlHelper。

Scott Hanselman在他的 “Splitting DateTime – Unit Testing ASP.NET MVC Custom Model Binders”中給出了一個(gè)并不是演示版的Model Binder,一個(gè)我需要提出來(lái)的細(xì)節(jié)是Scott的DateTime分離器仍然沒(méi)有通過(guò)Request.Form來(lái)綁定,在GetA<T> 方法中,你將會(huì)看到Scott使用了上下文對(duì)象的ValueProvider屬性來(lái)獲得數(shù)據(jù),ValueProvier表示混合了表單數(shù)據(jù),路由數(shù)據(jù),以及請(qǐng)求參數(shù)數(shù)據(jù)的數(shù)據(jù)。Scott的例子非常棒,但是,少了一個(gè)細(xì)節(jié):綁定中的錯(cuò)誤。

如果默認(rèn)的模型綁定器在將數(shù)據(jù)綁定到你的對(duì)象上時(shí)出現(xiàn)了問(wèn)題,它會(huì)將錯(cuò)誤信息和錯(cuò)誤的數(shù)據(jù)壓入到ModelState中,你可以檢查ModelState.IsValid來(lái)檢查綁定中的問(wèn)題,使用ModelState.AddModelError 方法可以注入你自己的錯(cuò)誤信息。

如果你看看Scott文章的回應(yīng),你會(huì)看到Sebastien Crocquesel’s 對(duì)這個(gè)問(wèn)題的補(bǔ)丁。如果轉(zhuǎn)換失敗,Sebastien的代碼將會(huì)使用ModelState.AddModelError方法來(lái)表示錯(cuò)誤。Controller和View都會(huì)使用ModelState來(lái)檢查綁定的問(wèn)題。Controller需要檢查ModelState,以便在將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)之前檢查錯(cuò)誤,而View需要通過(guò)ModelState來(lái)為用戶提供驗(yàn)證的回應(yīng)。需要注意的一點(diǎn)是HtmlHelper,你需要同時(shí)提供一個(gè)值,通過(guò)ModelState.SetModelValue,并且提供錯(cuò)誤信息,通過(guò)AddModelError,否則你將會(huì)得到一個(gè)運(yùn)行時(shí)的空引用異常,下面的代碼演示了這個(gè)問(wèn)題。

  1. [AcceptVerbs(HttpVerbs.Post)]   
  2.  
  3. public ActionResult Create(FormCollection Form)   
  4.  
  5. {   
  6.  
  7.     // this is the wrong approach ...   
  8.  
  9.     if (Form["Name"].Trim().Length == 0)   
  10.  
  11.         ModelState.AddModelError("Name", "Name is required");   
  12.  
  13.     
  14.  
  15.     return View();   
  16.  
  17. }   

上面的代碼創(chuàng)建了一個(gè)模型的錯(cuò)誤信息,但是沒(méi)有提供值。也有其他的問(wèn)題,但是,如果你像下面一場(chǎng)呈現(xiàn)視圖,那么,就會(huì)得到一個(gè)異常。

<%= Html.TextBox("Name", Model.Name) %>

縱然你為 Model.Name 提供了一個(gè)值,HtmlHelper 也會(huì)發(fā)現(xiàn)錯(cuò)誤,然后顯示試圖的值。如果你沒(méi)有提供值,就會(huì)看到一個(gè)空引用異常。

Tip#3通過(guò)繼承來(lái)自定義Model Binding

如果你決定實(shí)現(xiàn)一個(gè)自定義的Model Binder,你可能希望通過(guò)從DefaultModelBinder繼承來(lái)減少部分工作量,其實(shí),最終你會(huì)發(fā)現(xiàn)不能通過(guò)繼承DefaultModelBinder 來(lái)達(dá)到你的目的。例如,假如你希望通過(guò)自定義的 ModelBinder來(lái)創(chuàng)建某些對(duì)象,DefaultModelBinder將會(huì)使用Activator.CreateInstance和Model的默認(rèn)構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象,如果你的模型沒(méi)有提供默認(rèn)的構(gòu)造函數(shù),你可以重寫(xiě)CreateModel方法來(lái)解決這個(gè)問(wèn)題。

Jimmy有一篇關(guān)于使用DefaultModelBinder的派生類的帖子“A Better Model Binder”.

Tip#4使用注解來(lái)完成驗(yàn)證

Brad Wilson在他的文章DataAnnotations and ASP.NET MVC中,完美地演示了一切。

我建議你仔細(xì)讀一下Brad Wilson的文章,如果你想快一點(diǎn),這里總結(jié)了一下。

.NET 3.5 SP1帶來(lái)了System.ComponentModel.DataAnnotations程序集,通過(guò)數(shù)據(jù)的注解和DataAnnotationModelBinder,你可以處理大部分的服務(wù)器端驗(yàn)證問(wèn)題,只需要簡(jiǎn)單地標(biāo)注你的模型

  1. public class Recipe   
  2.  
  3. {   
  4.  
  5.     [Required(ErrorMessage="We need a name for this dish.")]   
  6.  
  7.     [RegularExpression("^Bacon")]    
  8.  
  9.     public string Name { get; set; }   
  10.  
  11.     
  12.  
  13.     // ...   
  14.  
  15. }   

Tip#5綁定和驗(yàn)證是兩個(gè)步驟

綁定是從環(huán)境中獲得數(shù)據(jù),然后賦予模型對(duì)象的過(guò)程,驗(yàn)證是檢查模型對(duì)象的數(shù)據(jù),確認(rèn)符合我們的期望。這是完全不同的操作,但是模型綁定模糊了他們的區(qū)別。如果你希望在Model Binder中一起完成這兩步工作,是可以的,這需要準(zhǔn)確地知道DataAnnotationsModelBinder做了什么,你可以看這幾個(gè)例子。實(shí)際上,經(jīng)常被忽略的一點(diǎn)是DefaultModelBinder如何分離綁定和驗(yàn)證步驟。如果只是簡(jiǎn)單屬性的驗(yàn)證,所有你要做的就是重寫(xiě)DefaultModelBinder的OnProperValidating方法。

下面的幾篇文章可以參考一下:

Tip#6關(guān)于綁定的內(nèi)容

前面我說(shuō)過(guò):Model Binder可以幫你從Request和HttpContext中擺脫出來(lái)。從更加廣泛的角度來(lái)說(shuō),并沒(méi)有限制數(shù)據(jù)的來(lái)源,請(qǐng)求上下文中包含豐富的客戶端信息。Scott Hanselman的另外一篇文章演示了將用戶的標(biāo)識(shí)綁定到模型上。

綜上所述

Model Binding是美妙的魔術(shù),所以,盡可能使用內(nèi)置的奇妙功能。

聲明:本網(wǎng)部份文章為轉(zhuǎn)載文章,在每篇文章底部有說(shuō)明,文章的觀點(diǎn)和立場(chǎng)僅代表作者個(gè)人立場(chǎng),不代表微網(wǎng)立場(chǎng),若是文章轉(zhuǎn)載中有侵范您的權(quán)益,請(qǐng)發(fā)郵件到 [email protected]或致電13922854199通知?jiǎng)h除,謝謝!

相關(guān)閱讀
ShopPro商城系統(tǒng) ShopPro跨境電商
開(kāi)啟電商新零售,盡在ShopPro