MVC3 ModelBinder

 

1、Model Binder从哪些地方获取数据(找到数据后会停止继续寻找)

MVC 框架内置默认的 Model Binder 是 DefaultModelBinder 类。当 Action Invoker 没找到自定义的 Binder 时,则默认使用 DefaultModelBinder。默认情况下,DefaultModelBinder 从如下 4 种途径查找要绑定到 Model 上的值:

  1. Request.Form,HTML form 元素提供的值。
  2. RouteData.Values,通过应用程序路由提供的值。
  3. Request.QueryString,所请求 URL 的 query string 值。
  4. Request.Files,客户端上传的文件。

如果是HttpGet:一般是从RouteData.Values获取路由的值

如果是HttpPost:一般是从Request.Form获取路由的值

 

2、绑定复合类型

绑定复合类型时会一一绑定复合类型的公共属性

也可以绑定数组:通过相同的Name属性绑定

也可以绑定到集合,具体参考:

http://www.cnblogs.com/willick/p/3424188.html#header_1

 

3、手动调用绑定(UpdateModel方法)

public ActionResult Address() {
    IList<Address> addresses = new List<Address>();
    UpdateModel(addresses, new FormValueProvider(ControllerContext));
    return View(addresses);
}

手动绑定即把从各种途径(主要由4个途径)获取的数据手动和Model进行绑定

 

4、自定义Model Binding(自定义绑定可对数据进行过滤及操作)

  4.1 继承于DefaultModelBinder

    

 public class MyModelBinder : DefaultModelBinder
    {

        protected override void SetProperty(ControllerContext controllerContext,
         ModelBindingContext bindingContext,
         System.ComponentModel.PropertyDescriptor propertyDescriptor, object value)
        {

            trim(propertyDescriptor, ref value);
            antiSqlInject(propertyDescriptor, ref value);

            base.SetProperty(controllerContext, bindingContext,
                                propertyDescriptor, value);
        }

        /// <summary>
        /// 去除两边空格
        /// </summary>
        /// <param name="propertyDescriptor"></param>
        /// <param name="value"></param>
        private void trim(System.ComponentModel.PropertyDescriptor propertyDescriptor, ref object value)
        {
            if (propertyDescriptor.PropertyType == typeof(string))
            {
                var stringValue = (string)value;
                if (!string.IsNullOrWhiteSpace(stringValue))
                {
                    stringValue = stringValue.Trim();
                }

                value = stringValue;
            }
        }

        /// <summary>
        /// 防止SQL注入
        /// </summary>
        /// <param name="propertyDescriptor"></param>
        /// <param name="value"></param>
        private void antiSqlInject(System.ComponentModel.PropertyDescriptor propertyDescriptor, ref object value)
        {
            if (propertyDescriptor.PropertyType == typeof(string))
            {
                var stringValue = (string)value;
                if (!string.IsNullOrWhiteSpace(stringValue))
                {
                    stringValue = AntiInjectUtil.StripAllTags(stringValue);
                }

                value = stringValue;
            }
        }

将默认的ModelBinder(DefaultModelBinder)替换为自定义的ModelBinder,作用于为全局

   protected void Application_Start()
        {
            ModelBinders.Binders.DefaultBinder = new MyModelBinder();
        }

 

     4.2 继承于IModelBinder

public class AddressBinder : IModelBinder {
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
        Address model = (Address)bindingContext.Model ?? new Address();
        model.City = GetValue(bindingContext, "City");
        model.Country = GetValue(bindingContext, "Country");
        return model;
    }

    private string GetValue(ModelBindingContext context, string name) {
        name = (context.ModelName == "" ? "" : context.ModelName + ".") + name;
        ValueProviderResult result = context.ValueProvider.GetValue(name);
        if (result == null || result.AttemptedValue == "") 
            return "<Not Specified>";
        else 
            return (string)result.AttemptedValue;
    }
}

注册ModelBinder

protected void Application_Start()
{

    ModelBinders.Binders.Add(typeof(Address), new AddressBinder());
}

 

 

 

posted @ 2014-04-10 16:38    阅读(1383)  评论(0编辑  收藏  举报