有时我们从客户端获取来的数据。不一定就是我们先要的,需要做一些处理 。这里我们以一个model的属性需要做处理为例子。
这里说5种解决方法。
model:
public class MyModel { public string Encrypt { get; set; } public string Lala { get; set; } }
Controller:
public class HomeController : Controller { public void Test(MyModel myModel) { } }
第一种方式:
在model里做处理,很简单也很方便,很好理解直接上代码
namespace WebApplication { public class MyModel { private string encryptValue = string.Empty; public string Encrypt { set { encryptValue = value; } get { return encryptValue + "uuu"; } } public string Lala { get; set; } } }
第二种方式:
实现一个默认的模型绑定重写GetPropertyValue方法。对反回的属性值处理。PS:GetPropertyValue—使用指定的控制器上下文、绑定上下文、属性描述符和属性联编程序来返回属性值。
首选我们要创建一个特性,用来标记需要做处理的属性
model:
namespace WebApplication { public class MyModel { [Test] public string Encrypt { get; set; } public string Lala { get; set; } } }
TestAttribute:用来标记的特性
namespace WebApplication { [AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=false)] public class TestAttribute:Attribute { } }
MyModelBinder:实现一个默认的模型绑定
调用父类方法获取属性值,如果满足条件,类型条件和标记条件,就返回自定义的值,否者返回原值
namespace WebApplication { public class MyModelBinder:DefaultModelBinder { protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) { var value = base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder); if(value is string &&propertyDescriptor.Attributes[typeof(TestAttribute)]!=null) { return "我对值做了处理"; } return value; } } }
添加默认模型绑定
namespace WebApplication { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //自定义默认模型绑定 ModelBinders.Binders.DefaultBinder = new MyModelBinder(); } } }
第三种方式:
实现一个自定义值提供器,ContainsPrefix方法判断是否满足条件,myModel:Controller里Action模型参数名
GetValue方式返回ValueProviderResult类型的结果,供模型绑定时使用
namespace WebApplication { public class MyValueProvider : IValueProvider { public MyValueProvider(string value) { this.Value = value; } private string Value { get; set; } public bool ContainsPrefix(string prefix) { if(prefix=="myModel") { return true; } else { return false; } } public ValueProviderResult GetValue(string key) { MyModel model = new MyModel() { Encrypt = this.Value + "ooo" }; return new ValueProviderResult( model, model.ToString(), CultureInfo.CurrentCulture); } } }
实现一个值提供器工厂:用来提供值提供器
namespace WebApplication { public class MyValueProviderFactory : ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { string value = controllerContext.HttpContext.Request["Encrypt"]; return new MyValueProvider(value); } } }
添加值提供器工厂
namespace WebApplication { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //添加一个值提供器工厂 ValueProviderFactories.Factories.Add(new MyValueProviderFactory()); } } }
第四种方式:
实现一个自定义值提供器工厂,myModel:Controller里Action模型参数名
把myModel作为Encrypt的前缀当做NameValueCollection的key保存起来,作为NameValueCollectionValueProvider的参数
模型是树状的,但是NameValueCollection是平面的,所以以添加前缀的方式保存数据。
namespace WebApplication { public class MyValueProviderFactory : ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { var value = controllerContext.HttpContext.Request["Encrypt"]; if (value == null) return null; NameValueCollection nameValueCollection = new NameValueCollection(); nameValueCollection.Add("myModel.Encrypt", "aaa" + value); return new NameValueCollectionValueProvider(nameValueCollection, CultureInfo.InvariantCulture); } } }
添加值提供器工厂
namespace WebApplication { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //添加一个值提供器工厂 ValueProviderFactories.Factories.Add(new MyValueProviderFactory()); } } }
第五种方式:
实现一个自定义模型绑定,bindingContext中获取当前的值,处理后返回一个model
namespace WebApplication { public class MyBinder:IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var value = bindingContext.ValueProvider.GetValue("Encrypt").AttemptedValue; return new MyModel { Encrypt = value + "ooxx" }; } } }
使用ModelBinder特性指定模型绑定
namespace WebApplication.Controllers { public class HomeController : Controller { public void Test([ModelBinder(typeof(MyBinder))] MyModel myModel) { } } }
学习和进步是一辈的事情,我们都因该不断努力去看一个更大更不一样的世界。
愿2016年,可以过的开开心心的,少些烦恼,做更优秀的项目和产品