一、内容协商的概念

HTTP规范将内容协商定义为“当有多个格式可用时为给定响应选择最佳格式的过程”。HTTP中内容协商的主要机制是这些请求标头:

Accept:响应可接受哪些媒体类型,例如“application / json”
Accept-Charset:可接受哪些字符集,例如UTF-8或ISO -。
Accept-Encoding:可接受哪些内容编码,例如gzip。
Accept-Language:首选的自然语言,例如“en-us”。

二、WebApi中序列化

如果Web API控制器将资源作为CLR类型返回,在管道将会将CLR类型序列化然后将其写入HTTP响应正文。

2.1  直接返回一个CLR对象

public Product GetProduct(int id)
{
var item = _products.FirstOrDefault(p => p.ID == id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}

客户端可能会发送此HTTP请求:

GET http://localhost.:21069/api/products/1 HTTP/1.1
Host: localhost.:
Accept: application/json, text/javascript, */*; q=0.01

作为响应,服务器可能会发送:

HTTP/1.1  OK
Content-Type: application/json; charset=utf-
Content-Length:
Connection: Close
{"Id":,"Name":"Gizmo","Category":"Widgets","Price":1.99}

  在这个栗子中,客户端请求JSON,Javascript或“任何”(* / *)。服务器使用Product对象的JSON表示进行响应。请注意,响应中的Content-Type标头设置为“application / json”。

2.2  控制器返回HttpResponseMessage对象

控制器还可以返回HttpResponseMessage对象,响应正文指定CLR对象时调用 CreateResponse 扩展方法:

public HttpResponseMessage GetProduct(int id)
{
  var item = _products.FirstOrDefault(p => p.ID == id);
  if (item == null)
  {
  throw new HttpResponseException(HttpStatusCode.NotFound);
  }
  return Request.CreateResponse(HttpStatusCode.OK, product,"application/json");
}

返回HttpResponseMessage时,我们可以更好地控制响应的详细信息。我们可以设置状态代码,添加HTTP标头,指定媒体格式等。

三、内容协商的工作原理

内容协商的工作过程可以分为三步:

第一步: 管道从HttpConfiguration对象获取IContentNegotiator服务 。

第二步: 从HttpConfiguration.Formatters集合中获取媒体格式化器列表 。

第三步: 管道调用IContentNegotiatior.Negotiate(type,request,famatters) 
  参数是:要序列化的对象类型,Request对象,媒体格式化器的集合
  返回结果:选用的格式化器,相应的媒体类型

这一步的过程是:Web API检测Request中Accept,Accept中有多种类型,从左到右,品质因子从高到低(默认q=1.0)并且同时尝试通过从格式化器列表中去找到一个匹配并且支持的媒体类。

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

很多情况下Request的Accept如上所示,如果Xml Formmatter存在,application/xml与Xml Formatter匹配上了,所以会以XML格式进行输出并返回。如果未找到格式化器,则Negotiate方法返回null,并且客户端接收HTTP错误406(不可接受)。

控制器如何直接调用内容协商的栗子:

public HttpResponseMessage GetProduct(int id)
{
var product = new Product()
{ Id = id, Name = "Gizmo", Category = "Widgets", Price = 1.99M };   //获取IContentNegotiator的服务实例
IContentNegotiator negotiator = this.Configuration.Services.GetContentNegotiator();   //Negotiate返会媒体类型和选择的formatter
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, // 序列化的对象
   result.Formatter, // 采用的formmter
   result.MediaType.MediaType // 媒体类型
    )
  };
}

如果想了解更多内容协商的内容,可以查看官网

Web API中的内容协商的更多相关文章

  1. 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理

    原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...

  2. Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化

    9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...

  3. ASP.NET Web API中的Controller

    虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...

  4. Web APi 2.0优点和特点?在Web APi中如何启动Session状态?

    前言 曾几何时,微软基于Web服务技术给出最流行的基于XML且以扩展名为.asmx结尾的Web Service,此服务在.NET Framework中风靡一时同时也被.NET业界同仁所青睐,几年后在此 ...

  5. 在ASP.NET Web API中使用OData

    http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...

  6. Web Api中的get传值和post传值

    GET 方式 get方式传参 我们一般用于获取数据做条件筛选,也就是 “查” 1.无参 var look = function () { $.ajax({ type: "GET", ...

  7. WEB API 中HTTP的get、post、put,delete 请求方式

    一.WEB API 中HTTP 请求方式的四个主要方法 (GET, PUT, POST, DELETE), 按照下列方式映射为 CURD 操作: 1.POST 用于新建资源,服务端在指定的URI 上创 ...

  8. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新 ...

  9. ASP.NET Web API 中的异常处理(转载)

    转载地址:ASP.NET Web API 中的异常处理

随机推荐

  1. Log Parser Studio 分析 IIS 日志

    Log Parser Studio 分析 IIS 日志 来源 https://www.cnblogs.com/lonelyxmas/p/8671336.html 软件下载地址: Log Parser ...

  2. linux tar 解压命令

    如果提示 common not find 先进行安装如下 wget http://www.rarsoft.com/rar/rarlinux-5.3.0.tar.gz tar -zxvf rarlinu ...

  3. [luogu4479][BJWC2018]第k大斜率【二维偏序+二分+离散化+树状数组】

    传送门 https://www.luogu.org/problemnew/show/P4479 题目描述 在平面直角坐标系上,有 n 个不同的点.任意两个不同的点确定了一条直线.请求出所有斜率存在的直 ...

  4. linux开发板出现Read-only file system的解决办法

    @2018-11-29 创建文件夹出现如下提示 mkdir: can't create directory 'test': Read-only file system 使用命令 mount rw -o ...

  5. UDS(ISO14229-2006) 汉译(No.7 应用层协议)

    标签:cte   amp   通信   pac   condition   man   没有   参数错误   family 7.1定义 应用层协议通常作为确认消息的传输,意味着从客户端发送的每一个请 ...

  6. zabbix添加ceph监控

    应用背景: 网上监控ceph集群的资料不算多,git上有个开源的监控项目,是跟zabbix结合的,主要包含一个shell写的脚本和zabbix监控模板,拿来测试小记一下. 开源地址: https:// ...

  7. java ee wildfly spring 在线程池的线程中注入

    public class RtmpSpyingTests extends AbstractTransactionalJUnit4SpringContextTests { @Autowired Thre ...

  8. A1140. Look-and-say Sequence

    Look-and-say sequence is a sequence of integers as the following: D, D1, D111, D113, D11231, D112213 ...

  9. jquery基本语法(一)

    https://www.cnblogs.com/haiyan123/p/7657151.html 一.jQuery基础1.为什么要用jquery?    写起来简单,省事,开发效率高,兼容性好2.什么 ...

  10. 逻辑回归 代价函数J关于系数theta求导

    J=-y*loga-(1-y)*log(1-a) 梯度下降,求dJ/d_theta_j