程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> 深入分析ASP.NET Mvc 1.0 – 4. 使用ModelBinder綁定Action的參數

深入分析ASP.NET Mvc 1.0 – 4. 使用ModelBinder綁定Action的參數

編輯:關於ASP.NET

在前一篇文章已經講敘Controller.Execute(…)方法的執行流程中會調用 ControllerActionInvoker類的 InvokeAction(ControllerContext controllerContext, string actionName)方法,在InvokeAction(…)方法內又調用了GetParameterValues(…) 方法,這個方法為Action中的每個參數賦值,追蹤到 GetParameterValues(…)方法內部 會發現其實每個參數的值是由GetParameterValue(…)返回的,觀察 GetParameterValue( …)方法的源碼:

protected virtual object GetParameterValue(ControllerContext  controllerContext, ParameterDescriptor parameterDescriptor) {
       // collect all of the necessary binding  properties
       Type parameterType = parameterDescriptor.ParameterType;
       IModelBinder binder = GetModelBinder (parameterDescriptor);
       IDictionary<string, ValueProviderResult> valueProvider  = controllerContext.Controller.ValueProvider;
       string parameterName =  parameterDescriptor.BindingInfo.Prefix ??  parameterDescriptor.ParameterName;
       Predicate<string> propertyFilter = GetPropertyFilter (parameterDescriptor);

       // finally, call into the binder
       ModelBindingContext bindingContext = new  ModelBindingContext() {
         FallbackToEmptyPrefix =  (parameterDescriptor.BindingInfo.Prefix == null), // only fall back if  prefix not specified 
         ModelName = parameterName,
         ModelState =  controllerContext.Controller.ViewData.ModelState,
         ModelType = parameterType,
         PropertyFilter = propertyFilter,
         ValueProvider = valueProvider
       };
       object result = binder.BindModel(controllerContext,  bindingContext);
       return result;
     }

代碼的邏輯分為:

獲取繼承了IModelBinder接口的對象

執行IModelBinder對象的BindModel(…)方法並返回Action的參數值

繼承IModelBinder接口的對象有三個類:DefaultModelBinder, FormCollectionModelBinder和HttpPostedFileBaseModelBinder

在GetParameterValue(…)方法中可以看到由GetModelBinder(parameterDescriptor) 負責返回IModelBinder對象,但他是如何確定返回哪個ModeBinder的呢?

當Action的參數類型為FormCollection時,GetParameterValue(…)方法返回 FormCollectoinModelBinder對象

當Action的參數類型為HttpPostedFileBase時,GetParameterValue(…)方法返回 HttpPostedFileBaseModelBinder對象

當Action的參數類型除了FormCollection和HttpPostedFileBase外(int, string, boolean或強類型),GetParameterValue(…)方法返回DefaultModelBinder對象, DefaultModelBinder也是最常用的ModelBinder

來深入到GetModelBinder(…)方法的內部

private IModelBinder GetModelBinder(ParameterDescriptor  parameterDescriptor) {
       // look on the parameter itself, then look in the  global table
       return parameterDescriptor.BindingInfo.Binder ??  Binders.GetBinder(parameterDescriptor.ParameterType);
     }

通常情況下IModelBinder都是由 Binders.GetBinder (parameterDescriptor.ParameterType)返回, Binders屬性調用ModelBinders.Binders 返回ModelBinderDictionary的靜態實例,在調用 ModelBinders.Binders屬性返回 ModelBinderDictionary對象之前先初始化 ModelBinderDictionary對象並將 HttpPostedFileBaseModelBinder保存到 ModelBinderDictionary對象中(代碼如下),最 後其實是調用ModelBinderDictionary的GetBinder()方法返回的IModelBinder對象。

public static class ModelBinders {
     private static readonly ModelBinderDictionary _binders =  CreateDefaultBinderDictionary();

     public static ModelBinderDictionary Binders {
       get {
         return _binders;
       }
     }

     private static ModelBinderDictionary  CreateDefaultBinderDictionary() {
       // We can't add a binder to the HttpPostedFileBase  type as an attribute, so we'll just
       // prepopulate the dictionary as a convenience to  users.

       ModelBinderDictionary binders = new ModelBinderDictionary()  {
         { typeof(HttpPostedFileBase), new  HttpPostedFileBaseModelBinder() }
       };
       return binders;
     }

   }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved