什么是ModelBinding
ASP.NET MVC中,所有的請求最終都會到達某個Controller中的某個Action并由該Action負責具體的處理和響應。為了能夠正確處理請求,Action的參數(如果有的話),必須在Action執行之前,根據相應的規則,把請求中所包含的數據提取出來并將映射為Action的參數值,這個過程就是ModelBinding。ModelBinding的作用就是為Action提供參數列表。
ModelBinding的好處
- 使代碼變得更加簡潔
- 幫助我們獲取HTTP請求中的數據
- 幫助我們完成必要的數據類型轉換
ASP.NET MVC中ModelBinding的實現過程
ASP.NET MVC中ModelBinding的實現過程比較復雜,這里簡要說明它的總體流程。具體的實現過程可以看蔣金楠的《ASP.NET MVC5框架揭秘》或者看他的博客How ASP.NET MVC Works?,講解很詳細。

- HTTP請求中的數據可能存在于querystring中,也可能在表單中,也有可能是JSON字符串。究竟從哪里獲取數據,這要依賴于參數的描述信息
ParameterDescriptor
ParameterDescriptor
的獲取需要借助于ControllerDescriptor
和ActionDescriptor
,它們分別用來描述Controller和ActionIModelBinderProvider
用于提供合適的ModelBinder對象,我們可以自己實現該接口以獲取自定義的IModelBinder
- ModelBinding的核心是
IModelBinder
,默認實現類是DefaultModelBinder
,我們可以自己實現IModelBinder
接口來擴展ModelBinder IValueProvider
針對不同的數據源提供了數據的訪問機制ValueProviderResult
提供了兩個ConvertTo方法重載以實現向指定目標類型的轉換。- 經過上述一系列的處理獲取最終結果
自定義ModelBinder
自定義Modelbinder只需實現System.Web.Mvc.IModelBinder
接口即可。這里需要注意一點,System.Web.ModelBinding
命名空間下也有一個IModelBinder
接口,不要搞錯了。
public class LessonEditInfoViewModelBinder : IModelBinder {//根據前臺傳遞的id值獲取對象public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext){var idStr = controllerContext.HttpContext.Request["id"] ?? controllerContext.RouteData.Values["id"]?.ToString();int id = 0;if (!int.TryParse(idStr, out id)){return null;}var model = new LessonBLL().GetLessonEditInfo(id);return model;} }
然后使用ModelBinderAttribute
進行標注即可:
/*根據前臺傳遞的id值解析出對象數據,Action無需關注對象的獲取,使代碼變得清晰簡潔 */ public ActionResult Edit([ModelBinder(typeof(LessonEditInfoViewModelBinder))]LessonEditInfoViewModel lesson) {if (lesson == null){//跨控制器的視圖跳轉要使用視圖的路徑+文件名return View("/Views/Exception/GenericError.cshtml", new ExceptionViewModel { Title = "404", Description = "課程不存在!" });}return View(lesson); }
如果項目中多處需要使用自定義的ModelBinder,那么再使用ModelBinderAttribute
進行標注就不大合適了。這種情況我們可以使用自定義的ModelBinderProvier。代碼如下:
public class CustomeModelBinderProvider : IModelBinderProvider {public IModelBinder GetBinder(Type modelType){if (modelType == typeof(LessonEditInfoViewModel)){return new LessonEditInfoViewModelBinder();}return null;} }
然后將自定義的ModelBinderProvider注冊到ASP.NET MVC系統中
public class MvcApplication : System.Web.HttpApplication {protected void Application_Start(){ModelBinderProviders.BinderProviders.Insert(0, new CustomeModelBinderProvider());} }
完成上述兩步之后,就無需使用ModelBuilderAttribute
進行標注了。
除此之外,還可在Global文件中使用使用ModelBinder
類的Binder
屬性來注冊ModelBinderProvider
ModelBinders.Binders.Add(typeof(LessonEditInfoViewModel),new LessonEditInfoViewModelBinder());
不同的ModelBinder提供策略有不同的優先級,具體如下:
- 在參數上使用CustomModelBinderAttribute
- 使用ModelBinderProviders.BinderProviers
- 使用ModelBinders.Binders
- 參數類型上標記CustomModelBinderAttribute
- ASP.NET MVC中提供的DefaultModelBinder
注意,CustomModelBinderAttribute是抽象類,在ASP.NET MVC中有唯一子類ModelBinderAttribute。
參考文章:
Model Binders in ASP.NET MVC
ModelBinder——ASP.NET MVC Model綁定的核心
ASP.NET MVC以ValueProvider為核心的值提供系統
玩轉Asp.net MVC 的八個擴展點
ASP.NET MVC中你必須知道的13個擴展點
版權聲明
本文為作者原創,版權歸作者雪飛鴻所有。 轉載必須保留文章的完整性,且在頁面明顯位置處標明原文鏈接。
如有問題, 請發送郵件和作者聯系。