Hello,World

ASP.NET WebAPI 05 参数绑定

 

ParameterBindingAttribute

在上一篇中重点讲了ModelBinderAttribute的使用场景。这一篇详细的讲一下ModelBinder背后的参数绑定原理。

ModelBinderAttribute继承自ParameterBindingAttribute,从命名上就是可以看出ParameterBindingAttribute是对Action参数进行绑定的一种特性。除了ModelBinderAttribute之外,WebAPI还另外定义了ValueProviderAttribute,FromUriAttribute与FromBodyAttribute三个ParameterBindingAttribute派生类。

 

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
    public abstract class ParameterBindingAttribute : Attribute
    {
        protected ParameterBindingAttribute();
        public abstract HttpParameterBinding GetBinding(HttpParameterDescriptor parameter);
}

 

  

 

 

ParameterBindingAttribute只提供了一个GetBinding方法,这个方法返回一个HttpParameterBinding类型对象,HttpParameterBinding是参数绑定过程中的一个核心类,它基本完成了从请求数据读取到参数绑定的整个过程。

 

在这里需要重点关注一下HttpParameterDescriptor,它做作为对参数的一个描述对象,包含了参数的一个信息(这个参后续还将详细讲解)

 

HttpParameterBinding

 

    public abstract class HttpParameterBinding
    {
        protected HttpParameterBinding(HttpParameterDescriptor descriptor);
        public HttpParameterDescriptor Descriptor { get; }        
        public virtual string ErrorMessage { get; }        
        public bool IsValid { get; }        
        public virtual bool WillReadBody { get; }

        public abstract Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken);
        
        protected object GetValue(HttpActionContext actionContext);

        protected void SetValue(HttpActionContext actionContext, object value);
}

 

  

 

 

其中ExecuteBindingAsync方法实现具体的参数绑定。对于来自Uri与Body的数据可通过WillReadBody进行区分,WillReadBody默认为false。

 

ModelBinderParameterBinding

 

现在我们回过头去再看上一篇的Model绑定。

 

 

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
    public class ModelBinderAttribute : ParameterBindingAttribute
    {
        public ModelBinderAttribute();
        public ModelBinderAttribute(Type binderType); 
        public Type BinderType { get; set; }
        public string Name { get; set; }
        public bool SuppressPrefixCheck { get; set; }
        public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter);      
        public IModelBinder GetModelBinder(HttpConfiguration configuration, Type modelType); 
        public ModelBinderProvider GetModelBinderProvider(HttpConfiguration configuration); 
        public virtual IEnumerable<System.Web.Http.ValueProviders.ValueProviderFactory> GetValueProviderFactories(HttpConfiguration configuration);
    }

 

  

 

 

 

在ModelBinderParameterBinding中定义了一个GetModelBinderProvider方法。ModelBinderProvider中定义一个GetBinder方法用于获取ModelBinder。

而ModelBinder正是完成Model绑定的基础类。

 

ModelBinderAttribute

FromUriAttribute

ValueProviderAttribute

FormatterParameterBinding

对于Body中的数据,WebAPI提供了FormatterParameterBinding进行数据绑定。由于Body可以提供的数据格式不像Uri那样单一,所以我们Body能够更加方便的为我们提供复杂的数据结构。FormatterParameterBinding从命名就可以看出来它提供将Body数据反序列化并绑定到参数的功能。

MediaTypeFormatter

对于不同的请求数据格式,FormatterParameter会根据请求的Conent-Type,提供不同的序列化对象。而这些序列化处理类型都继承于MediaTypeFormatter。

下面我列举一下Content-Type与MediaTypeFormatter的对应关系。

Content-Type

MediaTypeFormatter

text/xml,application/xml

XmlMediaTypeFormatter

text/json,application/json

MediaTypeFormatter

application/x-www-form-urlencoded

FormUrlEncodedMediaTypeFormatter

application/x-www-form-urlencoded

JqueryMvcFormUrlEncodedFormatter

 

FromBodyAttribute

 

IActionValueBinder

 

public interface IActionValueBinder

 { 

HttpActionBinding GetBinding(HttpActionDescriptor actionDescriptor); 

 }

 

  

 

 

绑定入口。

 

HttpActionBinding

 

public class HttpActionBinding

 { 

 

public HttpActionBinding(); 

 

public HttpActionBinding(HttpActionDescriptor actionDescriptor, HttpParameterBinding[] bindings); 

public HttpActionDescriptor ActionDescriptor { get; set; } 

 

public virtual Task ExecuteBindingAsync(HttpActionContext actionContext, CancellationToken cancellationToken); 

 } 

}

 

  

 

 

参数分离。

 

posted @ 2015-09-27 20:57  Barlow Du  阅读(1246)  评论(0编辑  收藏  举报