当前位置:编程学习 > asp >>

asp.net mvc源码分析-Action篇 IModelBinder

我们首先还是看看ReflectedParameterBindingInfo的Binder属性吧:

  public override IModelBinder Binder {
            get {
                IModelBinder binder = ModelBinders.GetBinderFromAttributes(_parameterInfo,
                    () => String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedParameterBindingInfo_MultipleConverterAttributes,
                        _parameterInfo.Name, _parameterInfo.Member));


                return binder;
            }
        }


在ModelBinders中有一个属性public static ModelBinderDictionary Binders,这个binders内容如下 

 ModelBinderDictionary binders =new ModelBinderDictionary(){
                { typeof(HttpPostedFileBase), new HttpPostedFileBaseModelBinder()},
                { typeof(byte[]), new ByteArrayModelBinder()},
                { typeof(Binary), new LinqBinaryModelBinder()}
            };
           说明默认的情况下就提供者3个Binder,但是这个属性是共有静态的,所以我们可以往里面添加自己的binder类,和前面文章讲的Filiter以及后面要讲的ValueProvider一样,

如在 Application_Start()方法中 ModelBinders.Binders.Add(xxx,xxxx)很不是很方便扩展了。

ModelBinders的GetBinderFromAttributes这个方法一看我们就能猜到它的逻辑了,


   CustomModelBinderAttribute[] attrs = (CustomModelBinderAttribute[])element.GetCustomAttributes(typeof(CustomModelBinderAttribute), true /* inherit */);


获取 当前参数的CustomModelBinderAttribute特性,如果有该特性就调用第一个特性的GetBinder()方法并返回其值,没有特性则返回null,如果有多个特性则抛出异常,说明一个参数上是不可以有多个CustomModelBinderAttribute特性的,正样 ReflectedParameterBindingInfo的binder属性就设置好了。

下面 该轮到ControllerActionInvoker的Binders属性,

 protected internal ModelBinderDictionary Binders {
            get {
                if (_binders == null) {
                    _binders = ModelBinders.Binders;
                }
                return _binders;
            }
            set {
                _binders = value;
            }
        }


可以 看到默认他返回的是ModelBinders.Binders。

接下来看看  IModelBinder binder = GetModelBinder(parameterDescriptor)这句究竟怎么返回的binder,

     return parameterDescriptor.BindingInfo.Binder ?? Binders.GetBinder(parameterDescriptor.ParameterType);


太简单了 ,首先看看参数是否有binder特性,如果有就返回相应的binder,否者根据参数类型获取对应的binder。

其 方法如下:


[csharp]
public IModelBinder GetBinder(Type modelType) { 
          return GetBinder(modelType, true /* fallbackToDefault */); 
      } 
 
      public virtual IModelBinder GetBinder(Type modelType, bool fallbackToDefault) { 
          if (modelType == null) { 
              throw new ArgumentNullException("modelType"); 
          } 
 
          return GetBinder(modelType, (fallbackToDefault) ? DefaultBinder : null); 
      } 
 
      private IModelBinder GetBinder(Type modelType, IModelBinder fallbackBinder) { 
 
          // Try to look up a binder for this type. We use this order of precedence:  
          // 1. Binder returned from provider  
          // 2. Binder registered in the global table  
          // 3. Binder attribute defined on the type  
          // 4. Supplied fallback binder  
 
          IModelBinder binder = _modelBinderProviders.GetBinder(modelType); 
          if (binder != null) { 
              return binder; 
          } 
 
          if (_innerDictionary.TryGetValue(modelType, out binder)) { 
              return binder; 
          } 
 
          binder = ModelBinders.GetBinderFromAttributes(modelType, 
              () => String.Format(CultureInfo.CurrentCulture, MvcResources.ModelBinderDictionary_MultipleAttributes, modelType.FullName)); 
 
          return binder ?? fallbackBinder; 
      } 

  public IModelBinder GetBinder(Type modelType) {
            return GetBinder(modelType, true /* fallbackToDefault */);
        }

        public virtual IModelBinder GetBinder(Type modelType, bool fallbackToDefault) {
            if (modelType == null) {
                throw new ArgumentNullException("modelType");
            }

            return GetBinder(modelType, (fallbackToDefault) ? DefaultBinder : null);
        }

        private IModelBinder GetBinde

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,