Content Negotiation的意思是:当有多种Content-Type可供选择时,选择最合适的一种进行序列化并返回给client。

主要依据请求中的Accept、Accept-Charset、Accept-Encoding、Accept-Language这些属性决定的,但也会查看其它属性

如,如果请求中包含“ X-Requested-With”(ajax请求),在没哟其它Accept时,则使用JSON。

Content Negotiation的工作原理

首先,pipeline从HttpConfiguration 对象中获得IContentNegotiator 服务,同时也会从 HttpConfiguration.Formatters中获得所有的media formatters 。接下来,pipeline调用 IContentNegotiatior.Negotiate传入一下值

  • 要序列化的对象
  • 所有media formatters
  • HTTP Request

Negotiate 返回2个值:

  • 选择的formatter
  • 要输出的media type

如果没有合适的formatter,Negotiate方法返回null,client会收到406错误(无法访问)

下面是一个controller直接使用content negotiation的例子“

 public HttpResponseMessage GetProduct(int id)
{
var product = new Product()
{ Id = id, Name = "Gizmo", Category = "Widgets", Price = 1.99M }; IContentNegotiator negotiator = this.Configuration.Services.GetContentNegotiator(); ContentNegotiationResult result = negotiator.Negotiate(
typeof(Product), this.Request, this.Configuration.Formatters);
if (result == null)
{
var response = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
throw new HttpResponseException(response));
} return new HttpResponseMessage()
{
Content = new ObjectContent<Product>(
product, // What we are serializing
result.Formatter, // The media formatter
result.MediaType.MediaType // The MIME type
)
};
}

默认的Content Negotiator

  DefaultContentNegotiator类是IContentNegotiator的默认实现,它使用以下标准选择formatter。

首先,这个类型必须能够序列化,这步验证通过MediaTypeFormatter.CanWriteType来实现

其次, content negotiator查看每个formatter并计算最与Http请求的formatter。匹配的原则如下:

  • SupportedMediaTypes 集合中包括所有的被支持的media type, content negotiator 使用Accept header与这个集合匹配。

注意,Accept Header可以是一个范围。例如,“text/plain”是text/*或"/"的匹配项

  • MediaTypeMappings 集合包含一系列的MediaTypeMappings 对象,它提供了http request与某种media type的匹配。如,

可以将自定义的Http Header与指定的media type对应

如果根据Accept Header没有找到合适的匹配项,ontent negotiator会尝试根据request body匹配media type。例如,如果请求包含JSON数据,content negotiator将使用 JSON formatter。

如果此时还没找到合适的匹配项,content negotiator会使用第一个可以序列化这个对象的formatter。

当formatter确定好后, content negotiator会查看这个formatter支持的SupportedEncodings ,并与 Accept-Charset header 进行匹配,查到最合适的 character encoding。

WebApi2官网学习记录---Content Negotiation的更多相关文章

  1. WebApi2官网学习记录---Configuring

    Configuration Settings WebAPI中的configuration settings定义在HttpConfiguration中.有一下成员: DependencyResolver ...

  2. WebApi2官网学习记录---Cookie

    Cookie的几个参数: Domain.Path.Expires.Max-Age 如果Expires与Max-Age都存在,Max-Age优先级高,如果都没有设置cookie会在会话结束后删除cook ...

  3. WebApi2官网学习记录---批量处理HTTP Message

    原文:Batching Handler for ASP.NET Web API 自定义实现HttpMessageHandler public class BatchHandler : HttpMess ...

  4. WebApi2官网学习记录---Html Form Data

    HTML Forms概述 <form action="api/values" method="post"> 默认的method是GET,如果使用GE ...

  5. WebApi2官网学习记录--HTTP Message Handlers

    Message Handlers是一个接收HTTP Request返回HTTP Response的类,继承自HttpMessageHandler 通常,一些列的message handler被链接到一 ...

  6. WebApi2官网学习记录---单元测试

    如果没有对应的web api模板,首先使用nuget进行安装 例子1: ProductController 是以硬编码的方式使用StoreAppContext类的实例,可以使用依赖注入模式,在外部指定 ...

  7. WebApi2官网学习记录---异常处理

    HttpResponseException 当WebAPI的控制器抛出一个未捕获的异常时,默认情况下,大多数异常被转为status code为500的http response即服务端错误. Http ...

  8. WebApi2官网学习记录---BSON

    BSON 是轻量级的,能够进行快速查询和高效的解码/编码.BSON方便查询是由于elements的前面都有一个表示长度的字段,所以解释器可以快速跳过这个elements:高效的解码/编码是因为nume ...

  9. WebApi2官网学习记录---JSON与XML的序列化

    JSON序列化: WebAPI的默认序列库使用的是Json.NET,可以在Globally中配置使用DataContractJsonSerializer 进行序列化 protected void Ap ...

随机推荐

  1. CSS3动画(360度旋转、旋转放大、放大、移动)

    Title div { width: 120px; height: 120px; line-height: 120px; margin: 20px; background-color: #5cb85c ...

  2. map的使用方法

    package cn.stat.p8.map.demo; import java.util.Collection; import java.util.HashMap; import java.util ...

  3. 动态代理写connection连接池Demo

    public class JdbcUtil2 { //声明连接池<放到LinkedList中,操作其中对象的速度快 只需要改变连接> private static LinkedList&l ...

  4. Spring框架知识总结-注入Bean的各类异常

    近日整合sping和hibernate框架时遇到了一系列的异常,本次主要说明一下spring框架可能出现的异常及解决方案. 我们借助sping强大的bean容器管理机制,通过BeanFactory轻松 ...

  5. C++ 完美破解九宫格(数独)游戏

    看到CSDN上有位大神用C#写了一个破解数独的程序(点击打开链接),不过我对C#也不懂,比较喜欢C++,就用标准C++也写了一个,希望各位喜欢.三纯程序,纯控制台程序,纯各人爱好,纯算法程序,无win ...

  6. 在Ajax中将数组转换成字符串(0517-am)

    一.如何在Ajax中将数组转换成字符串 1. 主页面; <head> <meta http-equiv="Content-Type" content=" ...

  7. VNC配置连接远程服务器桌面-linux\windows

    一.VNC配置连接远程服务器桌面 1.服务器安装VNC-server # yum -y install vnc-server 2.配置VNC连接登陆密码 # vncpasswd 回车 3.配置VNC- ...

  8. 分割gbk中文出现乱码的问题解决

    近日遇到一个神奇的字“弢(tao)”. 具体的过程是这样的: $list = explode('|', 'abc弢|bc'); var_dump($list); 取得这个分割的结果. 和想象不同,结果 ...

  9. MySQL按照汉字的拼音排序(转)

    按照汉字的拼音排序,用的比较多是在人名的排序中,按照姓氏的拼音字母,从A到Z排序: 如果存储姓名的字段采用的是GBK字符集,那就好办了,因为GBK内码编码时本身就采用了拼音排序的方法(常用一级汉字37 ...

  10. python django学习资料网站

    python module 模块 https://docs.python.org/2.7/py-modindex.html django框架例子 https://docs.djangoproject. ...