zoukankan      html  css  js  c++  java
  • 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); 
    
     } 
    
    }
    

      

    参数分离。

  • 相关阅读:
    移动银盘 文件或目录损坏且无法读取 提示格式化
    error: Some data has already been output, can't send PDF file
    php pdf english french duch……应用攻略,ufpdf
    photoshop cs4 多语言
    c++常用知识小结
    简单的排序
    内存对齐
    socket网络编程常用的结构及函数小结
    字符和字符串处理小结
    几个小程序
  • 原文地址:https://www.cnblogs.com/gangtianci/p/4842744.html
Copyright © 2011-2022 走看看