本章介绍了值提供器的作用,ASP MVC自带的5中值提供器.以及模型绑定器的作用,自定义模型绑定器并使用自定义的模型绑定器(类型上加上[ModelBinder(typeof(xx))]或者在全局模型绑定器中注册)。

补充:全局模型绑定器中注册自定义模型绑定器

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    ModelBinders.Binders.Add(typeof(Point), new PointModelBinder());
}

 

 

 

 

 

值提供器

ASP .NET MVC 框架自带的若干值提供器可以提供以下数据源中的数据:
●  子操作(RenderAction)的显式值
●  表单值
●  来自 XMLHttpRequest 的 JSON 数据
●  路由值
●  查询字符串值
●  上传的文件
值提供器来自值提供器工厂,并且系统按照值提供器的注册顺序来从中搜寻数据(上面
的列表使用的是默认顺序,自顶而下)。开发人员可以编写自己的值提供器工厂和值提供器,
并且还可以将它们插入到包含在 ValueProviderFactories.Factories 中的工厂列表中。当在模
型绑定期间需要使用额外的数据源时,开发人员通常选择编写自己的值提供器工厂和值提
供器。

 

 

除了 ASP .NET  MVC 本身包含的值提供器工厂以外,开发团队也在 ASP.NET  MVC  3
Futures 包中包含了一些提供器工厂和值提供器,可从 http://aspnet.codeplex.com/releases/view/
58781 上下载,或者安装 NuGet 包 Mvc3Futures。具体包括以下提供器:
●  Cookie 值提供器
●  服务器变量值提供器
●  Session 值提供器
●  TempData 值提供器

 

 

模型绑定器

 

1.作用

模型扩展的另一部分是模型绑定器。它们从值提供器系统中获取值,并利用获取的值创建新模型或者填充已有的模型。

模型绑定器,从值提供器中获取值。

 

ASP .NET  MVC 中的默认模型绑定器( 为方便起见,命名为DefaultModelBinder)是一段功能非常强大的代码,它可以对传统类、集合类、列表、数组 甚至字典进行模型绑定。

但是不支持对不改变对象的模型绑定(不可变指的是只能通过构造函数初始化值的类),如果遇见不可变的对象或者类型则默认的模型绑定器就无用了。此时需要自定义模型绑定器

 

2. 自定义模型绑定器

 

实现IModelBinder接口的 BinderModel方法

object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)

 

主要是用到ModelBindingContext类

 

假设要对Point类进行模型绑定(Point类只能通过构造函数进行初始化,所以只能通过自定义模型提供器)

 

下面是Point类代码和自定义模型绑定器代码

 

  • using System;
  • using System.Collections.Generic;
  • using System.Linq;
  • using System.Web;
  •  
  • using System.Web.Mvc; //IModelBinder
  •  
  • namespace MvcApplication1.Sample_ModelBinder
  • {
  •  
  •     public class TestModelBinder : IModelBinder
  •     {
  •  
  •         public object BindModel(ControllerContext controllerContext,
  •         ModelBindingContext bindingContext)
  •         {
  •             var valueProvider = bindingContext.ValueProvider;
  •           
  •                 int x = (int)valueProvider.GetValue("X").ConvertTo(typeof(int));
  •                 int y = (int)valueProvider.GetValue("Y").ConvertTo(typeof(int));
  •  
  •            
  •            
  •             return new Point(x, y);
  •         }
  •     }
  •  
  •  
  •  
  •     public class PointModelBinder : IModelBinder
  •     {
  •         //public object BindModel(ControllerContext controllerContext,
  •         //ModelBindingContext bindingContext)
  •         //{
  •         //    var valueProvider = bindingContext.ValueProvider;
  •         //    int x = (int)valueProvider.GetValue("X").ConvertTo(typeof(int));
  •         //    int y = (int)valueProvider.GetValue("Y").ConvertTo(typeof(int));
  •         //    return new Point(x, y);
  •         //}
  •  
  •  
  •         private TModel Get<TModel>(ControllerContext controllerContext,ModelBindingContext bindingContext,string name)
  •         {
  •             string fullName = name;
  •             //1.modelname
  •             if (!String.IsNullOrWhiteSpace(bindingContext.ModelName))
  •                 fullName = bindingContext.ModelName + "." + name;
  •  
  •             //2.,valueProviderResult
  •                 ValueProviderResult valueProviderResult =bindingContext.ValueProvider.GetValue(fullName);
  •             //3.modelState
  •                 ModelState modelState = new ModelState { Value = valueProviderResult };
  •             //4.ModelstatebindingContext.ModelState
  •                 bindingContext.ModelState.Add(fullName, modelState);
  •             //5.null
  •                 ModelMetadata metadata = bindingContext.PropertyMetadata[name];
  •                 string attemptedValue = valueProviderResult.AttemptedValue;
  •                 if (metadata.ConvertEmptyStringToNull&& String.IsNullOrWhiteSpace(attemptedValue))
  •                     attemptedValue = null;
  •  
  •             //6.  
  •                 TModel model;
  •                 bool invalidValue = false;
  •                 try
  •                 {
  •                     model = (TModel)valueProviderResult.ConvertTo(typeof(TModel));
  •                     metadata.Model = model;                  //XX
  •                 }
  •                 catch (Exception)
  •                 {
  •                     model = default(TModel);             //int 0.boolfalse,null
  •                     metadata.Model = attemptedValue;
  •                     invalidValue = true;              //null
  •                 }
  •  
  •  
  •             ///
  •                 IEnumerable<ModelValidator> validators =
  •                 ModelValidatorProviders.Providers.GetValidators(
  •                 metadata,
  •                 controllerContext
  •                 );
  •             
  •                 foreach (var validator in validators)
  •                     foreach (var validatorResult in
  •                     validator.Validate(bindingContext.Model))
  •                         modelState.Errors.Add(validatorResult.Message);
  •                 if (invalidValue && modelState.Errors.Count == 0)
  •                     modelState.Errors.Add(
  •                     String.Format(
  •                     "The value '{0}' is not a valid value forr {1}.",
  •                     attemptedValue,
  •                     metadata.GetDisplayName()
  •                     )
  •                     );
  •                 return model;
  •         }
  •         public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  •         {
  •  
  •             //1.modelname object
  •             //
  •             if (!String.IsNullOrEmpty(bindingContext.ModelName) &&
  •                 !bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
  •             {
  •                 if (!bindingContext.FallbackToEmptyPrefix)
  •                     return null;
  •                 bindingContext = new ModelBindingContext
  •                 {
  •                     ModelMetadata = bindingContext.ModelMetadata,
  •  
  •                     ModelState = bindingContext.ModelState,
  •                     PropertyFilter = bindingContext.PropertyFilter,
  •                     ValueProvider = bindingContext.ValueProvider
  •                 };
  •             }
  •  
  •             bindingContext.ModelMetadata.Model = new Point();
  •  
  •             return new Point(Get<int>(controllerContext, bindingContext, "X"), Get<int>(controllerContext, bindingContext, "Y"));
  •  
  •         }
  •  
  •     }
  •     [ModelBinder(typeof(PointModelBinder))]
  •     //[ModelBinder(typeof(TestModelBinder))]
  •     public class Point
  •     {
  •         private int x;
  •  
  •         public int X
  •         {
  •             get { return x; }
  •           
  •             set { x = value;}  //
  •         }
  •     
  •         private int y;
  •  
  •     public int Y
  •     {
  •         get { return y;}
  •         set { y = value;}
  •     }
  •     
  •  
  •  
  •         public Point(int x, int y)
  •         {
  •             this.x = x;
  •             this.y = y;
  •         }
  •         public Point()
  •         {
  •  
  •         }
  •     }
  • }
  • 相关文章:

    • 2021-12-16
    • 2022-12-23
    • 2021-09-07
    • 2021-05-02
    • 2021-06-12
    • 2022-12-23
    猜你喜欢
    • 2022-12-23
    • 2021-11-02
    • 2022-12-23
    • 2022-02-16
    • 2022-12-23
    • 2022-12-23
    • 2022-12-23
    相关资源
    相似解决方案