Web API中的内容协商
一、内容协商的概念
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中的内容协商的更多相关文章
- 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理
原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
- ASP.NET Web API中的Controller
虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...
- Web APi 2.0优点和特点?在Web APi中如何启动Session状态?
前言 曾几何时,微软基于Web服务技术给出最流行的基于XML且以扩展名为.asmx结尾的Web Service,此服务在.NET Framework中风靡一时同时也被.NET业界同仁所青睐,几年后在此 ...
- 在ASP.NET Web API中使用OData
http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...
- Web Api中的get传值和post传值
GET 方式 get方式传参 我们一般用于获取数据做条件筛选,也就是 “查” 1.无参 var look = function () { $.ajax({ type: "GET", ...
- WEB API 中HTTP的get、post、put,delete 请求方式
一.WEB API 中HTTP 请求方式的四个主要方法 (GET, PUT, POST, DELETE), 按照下列方式映射为 CURD 操作: 1.POST 用于新建资源,服务端在指定的URI 上创 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新 ...
- ASP.NET Web API 中的异常处理(转载)
转载地址:ASP.NET Web API 中的异常处理
随机推荐
- P1091 合唱队形 最长上升子序列
思路:最长上升子序列 正着做一遍 倒着做一遍 然后 取最大值 #include<bits/stdc++.h> using namespace std; const int maxn=105 ...
- Codeforces997D Cycles in product 【FFT】【树形DP】
题目大意: 给两个树,求环的个数. 题目分析: 出题人摆错题号系列. 通过画图很容易就能想到把新图拆在两个树上,在树上游走成环. 考虑DP状态F,G,T.F表示最终答案,T表示儿子不考虑父亲,G表示父 ...
- android打电话方法(直接拨通)
新建了CallPhone方法,如下: private void CallPhone() { String number = et_number.getText().toString(); if (Te ...
- BZOJ 1497 最大获利
最大权闭合子图 对于这个题,可以抽象成一个图论模型,如果我们把用户与其要求建立的中转站连边,获得的利益看成正权值,付出的代价看成负权值,我们可以发现,选取一个用户的时候,就相当于选取了一个闭合子图. ...
- 「POJ3311」Hie with the Pie
题目链接 >http://poj.org/problem?id=3311< 题意:从0出发,经过所有点(点可以重复走)后回到0点,问最短路 思路分析: 这题和普通的最短路不太一样,因为题目 ...
- WIN8.1下Prolific USB-to-Serial Comm Port驱动黄色感叹号问题
文章解决来源:http://blog.csdn.net/gsj0791/article/details/17664861 在做fpga口的uart回环测试时候,由于开发板上的是usb转uart,所以需 ...
- 【CF809C】Find a car(动态规划)
[CF809C]Find a car(动态规划) 题面 洛谷 CF 有一个无穷大的矩阵,第\(i\)行第\(j\)列的数是\((i-1)xor(j-1)+1\),\(q\)次询问,每次询问一个矩形内数 ...
- layer 弹出层
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Apache Beam实战指南 | 手把手教你玩转KafkaIO与Flink
https://mp.weixin.qq.com/s?__biz=MzU1NDA4NjU2MA==&mid=2247492538&idx=2&sn=9a2bd9fe2d7fd6 ...
- Java 并发集合的实现原理
http://www.codeceo.com/article/the-implementation-principle-of-java-concurrent-collection.html 阿凡卢 ...