Model绑定的数据具有多种来源:
- 提交的表单
- Json字符串
- 当前路由数据
- 请求地址的查询字符串
ASP.NET MVC将这种基于不同数据来源的数据提供机制实现在ValueProvider的组件中
ValueProvider采用的数据结构是字典类型
ValueProvider实现了具有System.Web.Mvc.IValueProvider的接口
1 public interface IValueProvider 2 { 3 //判断数据源容器中是否有指定前缀的key 4 bool ContainsPrefix(string prefix); 5 //根据key找到指定的数据 6 ValueProviderResult GetValue(string key); 7 8 }
GetValue返回的是一个System.Web.Mvc.ValueProviderResult对象,提供的数据包含在该对象中。
1 public class ValueProviderResult 2 { 3 public ValueProviderResult(object rawValue,string attemptedValue,CultrueInfo culture); 4 //实现向指定目标类型的转换 5 public object ConvertTo(Type type); 6 public virtual object ConvertTo(Type type,CultureInfo culture); 7 8 //数据值的字符串表示 9 public string AttemptedValue{get;} 10 11 public CultrueInfo cultrue{get;} 12 //原始数据 13 public object RawValue{get;} 14 15 }
NameValueCollectionValueProvider
表示一种Key和Value均为字符串的字典,并且对Key不具有唯一性约束(两个元素可以共享相同的key)
public class NameValueCollectionValueProvider:IUnvalidateValueProvider,IEnumerableValueProvider,IValueProvider
IEnumerableValueProvider主要针对于目标类型为集合的数据提供
IUnvalidateValueProvider,提供了额外的getValue(),使我们可以忽略对数据的验证
针对NameValueCollectionValueProvider的数据提供实现由两个具体的实现类:
1 //提交表单 2 FormValueProvider:NameValueCollectionValueProvider 3 //请求查询字符串 4 QueryStringValueProvider:NameValueCollectionValueProvider
DictionaryValueProvider
这是一个真正的字典对象。
它与NameValueCollection不同之处在于:
NameValueCollection中的元素仅限于字符串,并且不对key进行唯一性约束
字典中的key具有唯一性,Value也不仅仅局限于字符串
针对DictionaryValueProvider的数据提供实现由两个具体的实现类:
//通过url路由系统解析请求地址得到的路由数据,可以作为Model绑定的数据来源 RouteDataValueProvider:DictionaryValueProvider<object> //对上传文件获取的数据 HttpFileCollectionValueProvider:DictionaryValueProvider<HttpPostedFileBase[]> // ChildActionValueProvider:DictionaryValueProvider<object>
ValueProviderFactory
ValueProviderFactory是创建ValueProvider的工厂,它继承自如下的抽象类
1 public abstract class ValueProviderFactory 2 { 3 //根据当前ControllerContext创建相应的ValueProvider对象 4 public abstract IValueProvider GetValueProvider(ControllerContext controllerContext); 5 }
在System.Web.Mvc命名空间下ASP.NET MVC定义了一系列具体的ValueProviderFactory类型。
下面的列表列出了定义在Model绑定系统中的6个原生的ValueProviderFactory:
- ChildActionValueProviderFactory:根据给定的Controller上下文创建一个ChildActionValueProvider对象。
- FormValueProviderFactory:根据给定的Controller上下文创建一个FormValueProvider对象。
- JsonValueProviderFactory:将以JSON形式表示的请求数据转换成一个Dictionary<string, object>对象,并最终创建一个DictionaryValueProvider<object>对象。
- RouteDataValueProviderFactory:根据给定的Controller上下文创建一个RouteDataValueProvider对象。
- QueryStringValueProviderFactory:根据给定的Controller上下文创建一个QueryStringValueProvider对象。
- HttpFileCollectionValueProviderFactory:根据给定的Controller上下文创建一个HttpFileCollectionValueProvider对象。
ValueProviderFactory的注册
ValueProviderFactory在ASP.NET MVC应用中的注册通过静态类型ValueProviderFactories实现。如下面的代码片断所示,ValueProviderFactories具有一个静态只读属性Factories返回一个表示ValueProviderFactory集合的ValueProviderFactoryCollection类型。
1: public static class ValueProviderFactories 2: { 3: public static ValueProviderFactoryCollection Factories { get; } 4: } 5: 6: public class ValueProviderFactoryCollection : Collection<ValueProviderFactory> 7: { 8: public ValueProviderFactoryCollection(); 9: public ValueProviderFactoryCollection(IList<ValueProviderFactory> list); 10: public IValueProvider GetValueProvider(ControllerContext controllerContext); 11: }
ValueProviderFactoryCollection的GetValueProvider方法返回的是一个ValueProviderCollection对象,集合中的每个ValueProvider通过对应的ValueProviderFactory来创建。ValueProviderFactory在ValueProviderFactoryCollection集合中的先后次序决定了创建的ValueProvider在ValueProviderCollection中的次序,而次序决定了使用优先级。
在默认的情况下ValueProviderFactories的Factories属性表示的ValueProviderFactoryCollection包含了上面我们介绍的6种ValueProviderFactory,次序(优先级)为:ChildActionValueProviderFactory、FormValueProviderFactory、JsonValueProviderFactory、RouteDataValueProviderFactory、QueryStringValueProviderFactory和。如果具有相同的名称的请求书去同时存在于请求表单和查询字符串中,前者会被选用。
以ValueProvider为核心的值提供系统中涉及到了三类组件/类型,即用于具体实现数据值提供的ValueProvider,ValueProvider通过ValueProviderFactotry,而ValueProviderFactotry通过ValueProviderFactotries进行注册。图5-4所示的UML体现了三者之间的关系。