1、Model Binder从哪些地方获取数据(找到数据后会停止继续寻找)
MVC 框架内置默认的 Model Binder 是 DefaultModelBinder 类。当 Action Invoker 没找到自定义的 Binder 时,则默认使用 DefaultModelBinder。默认情况下,DefaultModelBinder 从如下 4 种途径查找要绑定到 Model 上的值:
- Request.Form,HTML form 元素提供的值。
- RouteData.Values,通过应用程序路由提供的值。
- Request.QueryString,所请求 URL 的 query string 值。
- Request.Files,客户端上传的文件。
如果是HttpGet:一般是从RouteData.Values获取路由的值
如果是HttpPost:一般是从Request.Form获取路由的值
2、绑定复合类型
绑定复合类型时会一一绑定复合类型的公共属性
也可以绑定数组:通过相同的Name属性绑定
也可以绑定到集合,具体参考:
3、手动调用绑定(UpdateModel方法)
public ActionResult Address() { IList addresses = new List(); 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); } ////// 去除两边空格 /// /// /// 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; } } ////// 防止SQL注入 /// /// /// 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 ""; else return (string)result.AttemptedValue; }}
注册ModelBinder
protected void Application_Start(){ ModelBinders.Binders.Add(typeof(Address), new AddressBinder());}