你的位置:首页 > ASP.net教程

[ASP.net教程]模型绑定时对客户端传过来的数据做处理的几种方式


有时我们从客户端获取来的数据。不一定就是我们先要的,需要做一些处理 。这里我们以一个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年,可以过的开开心心的,少些烦恼,做更优秀的项目和产品