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); 

 } 

}

  

参数分离。

ASP.NET WebAPI 05 参数绑定的更多相关文章

  1. Parameter Binding in ASP.NET Web API(参数绑定)

    Parameter Binding in ASP.NET Web API(参数绑定) 导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnbl ...

  2. Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)

    导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html. 本文主要来讲解以下内容: ...

  3. WebAPI 2参数绑定方法

    简单类型参数 Example 1: Sending a simple parameter in the Url [RoutePrefix("api/values")] public ...

  4. ASP.NET WebAPI 11 参数验证

    在绑定完Action的所有参数后,WebAPI并不会马上执行该方法,而要对参数进行验证,以保证输入的合法性. ModelState 在ApiController中一个ModelState属性用来获取参 ...

  5. ASP.NET WebAPI 04 Model绑定

    在前面的几篇文章中我们都是采用在URI中元数据类型进行传参,实际上ASP.NET Web API也提供了对URI进行复杂参数的绑定方式--Model绑定.这里的Model可以简单的理解为目标Ancti ...

  6. Asp.net WebAPI Request参数验证-请不要重复造轮子

    随着web客户端的发展,现在很多公司都有专业的前端开发,做到系统前后端分离.ap.net后端典型的就是采用webapi,但是发现很多时候大家对webapi并不了解,这里我们来说说输入参数的验证.前一段 ...

  7. WebApi 参数绑定方法

    WebAPI 2参数绑定方法   简单类型参数 Example 1: Sending a simple parameter in the Url 01 02 03 04 05 06 07 08 09 ...

  8. [译]WebAPI下的如何实现参数绑定

    本文将概述在WebAPI方式下将如何将参数绑定到一个action方法,包括参数是如何被读取,一系列规则决定特定环境采用的那种绑定方式,文章最后将给出一些实际的例子. Parameter binding ...

  9. 使用ASP.Net WebAPI构建REST服务(四)——参数绑定

    默认绑定方式 WebAPI把参数分成了简单类型和复杂类型: 简单类型主要包括CLR的primitive types,(int.double.bool等),系统内置的几个strcut类型(TimeSpa ...

随机推荐

  1. Codeforces 934.C A Twisty Movement

    C. A Twisty Movement time limit per test 1 second memory limit per test 256 megabytes input standard ...

  2. centos7下安装配置jenkins+git+maven+jdk

    环境 centos7 jdk1.8 maven3 git 在安装jenkins之前,先安装jdk1.8.maven.git 一. 安装jdk1.8 第一步:下载 jdk-8u131-linux-x64 ...

  3. [Thu Summer Camp 2015]解密运算

    4104: [Thu Summer Camp 2015]解密运算 Time Limit: 10 Sec  Memory Limit: 512 MB Description 对于一个长度为N的字符串,我 ...

  4. 莫队+分块 BZOJ 3809

    3809: Gty的二逼妹子序列 Time Limit: 80 Sec  Memory Limit: 28 MBSubmit: 1634  Solved: 482[Submit][Status][Di ...

  5. HDU 1812 polya 大数

    由于反射的存在,分奇偶讨论其置换的循环节数量,大数用JAVA就好了. import java.math.*; import java.util.*; public class Main{ public ...

  6. HDU 1333 基础数论 暴力

    定义一种数位simth数,该数的各位之和等于其所有质因子所有位数字之和,现给出n求大于n的最小该种数,n最大不超过8位,那么直接暴力就可以了. /** @Date : 2017-09-08 14:12 ...

  7. LightOJ1214 Large Division 基础数论+同余定理

    Given two integers, a and b, you should check whether a is divisible by b or not. We know that an in ...

  8. SQLServer字符串的一些截取技巧

    先看一张科学家的生卒年月表 截取科学家的出生年份可以很方便的用left函数截取,如果要截取去世年份,需要先获取字符“—”的位置. select substring(c,charindex('—',c) ...

  9. [Luogu 2024] 食物链

    [Luogu 2024] 食物链 几句随感 我依稀记得联赛前本来想做这题的时候. 当年啊弱到题目与标签就令我望而生畏. 还有翻阅很多遍那现在已经被遗弃的博客. 看到题解中「三倍数组」的字眼就怕难而放弃 ...

  10. PHP扩展开发--01.编写一个helloWorld扩展

    为什么要用C扩展 C是静态编译的,执行效率比PHP代码高很多.同样的运算代码,使用C来开发,性能会比PHP要提升数百倍. 另外C扩展是在进程启动时加载的,PHP代码只能操作Request生命周期的数据 ...