Content Negotiation in ASP.NET Web API
本文描述Web API实现内容协商(content negotiation)。
The HTTP specification (RFC 2616) defines content negotiation as “the process of selecting the best representation for a given response when there are multiple representations available.”
HTTP中内容协商机制是由以下请求头实现的:
- Accept: 响应支持的媒体类型, 比如 “application/json,” “application/xml,” 或者自定义的媒体类型如 "application/vnd.example+xml"
- Accept-Charset: 接受哪种字符集,例如 UTF-8 或 ISO 8859-1.
- Accept-Encoding: 接受哪种内容编码,例如 gzip.
- Accept-Language: 优先支持的自然语言,例如 “en-us”.
如果没有Accept头部,服务器也可以通过查看其它部分来决定。例如,如果头部包含X-Requested-With,表明是一个AJAX请求,那么服务器默认选择JSON格式。
本文中,我们将看到Web API使用Accept和Accept-Charset头部.(目前为止,没有内置的实现支持Accept-Encoding或者Accept-Language)
1. 序列化
如果Web API返回一个CLR类型,那么闲序列化,然后写到HTTP的响应体。
如果客户端的请求为:
GET http://localhost.:21069/api/products/1 HTTP/1.1
Host: localhost.:21069
Accept: application/json, text/javascript, */*; q=0.01
那么,很可能就返回
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 57
Connection: Close
{"Id":1,"Name":"Gizmo","Category":"Widgets","Price":1.99}
序列化资源的对象称为媒体格式化器(media formatter)。查看MediaTypeFormatter类,Web API默认支持XML和JSON,也可以自定义。
2. 内容协商怎么工作?
首先,Web API管道从HttpConfiguration对象获取IContentNegotiator服务,IContentNegotiator服务从HttpConfiguration.Formatters集合获取到_媒体格式化器_,
接着,管道调用IContentNegotiatior.Negotiate,传递:
要序列化的类型
媒体格式化器列表
HTTP 请求
Negotiate方法返回两部分信息:
使用哪个媒体格式化器(media formatter)
返回什么媒体类型(media type)
如果找不到格式器,Negotiate方法返回null,客户端收到一个406(Not Acceptable)错误。
解释内容协商的演示代码:
public HttpResponseMessage GetProduct(int id, bool contentNegotiate)
{
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
)
};
}
管道就如上述代码一样自动处理的。
默认的内容协商
DefaultContentNegotiator是IContentNegotiator的默认实现。
首先,媒体格式化器(formatter)要能够序列化当前类型,CanWriteType方法来验证的。
接着,内容协商器查看每一个媒体格式化器,并计算和HTTP请求的匹配度。
SupportedMediaTypes集合。内容协商器匹配每一个Accept头部
MediaTypeMappings集合。
如果有多个匹配,选择质量因子最高的一个。
Accept: application/json, application/xml; q=0.9, */*; q=0.1
如上,application/json将是最优的。
如果没有任何的匹配,那么内容协商器将匹配请求体,如果请求体是JSON数据,那么内容协商器将寻找一个JSON序列化器。
如果仍没有匹配,那么内容协商器将简单地选择第一个能够序列化当前类型的序列化器。
3. 字符编码选择
序列化器选定之后,通过序列化器上的SupportedEncodings属性来选择最好的内容编码,并且与Accept-Charset头部能够匹配。
Content Negotiation in ASP.NET Web API的更多相关文章
- 【ASP.NET Web API教程】6 格式化与模型绑定
原文:[ASP.NET Web API教程]6 格式化与模型绑定 6 Formats and Model Binding 6 格式化与模型绑定 本文引自:http://www.asp.net/web- ...
- Asp.Net Web API 2第十四课——Content Negotiation(内容协商)
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...
- ASP.NET Web API - ASP.NET MVC 4 系列
Web API 项目是 Windows 通信接口(Windows Communication Foundation,WCF)团队及其用户激情下的产物,他们想与 HTTP 深度整合.WCF ...
- ASP.NET Web API系列教程目录
ASP.NET Web API系列教程目录 Introduction:What's This New Web API?引子:新的Web API是什么? Chapter 1: Getting Start ...
- 【ASP.NET Web API教程】6.3 内容协商
本文是Web API系列教程的第6.3小节 6.3 Content Negotiation 6.3 内容协商 摘自:http://www.asp.net/web-api/overview/format ...
- 让ASP.NET Web API支持text/plain内容协商
ASP.NET Web API的内容协商(Content Negotiation)机制的理想情况是这样的:客户端在请求头的Accept字段中指定什么样的MIME类型,Web API服务端就返回对应的M ...
- 【转】WCF和ASP.NET Web API在应用上的选择
文章出处:http://www.cnblogs.com/shanyou/archive/2012/09/26/2704814.html 在最近发布的Visual Studio 2012及.NET 4. ...
- ASP.NET Web API——选择Web API还是WCF
WCF是.NET平台服务开发的一站式框架,那么为什么还要有ASP.NET Web API呢?简单来说,ASP.NET Web API的设计和构建只考虑了一件事情,那就是HTTP,而WCF的设计主要是考 ...
- asp.net web api的自托管模式HttpSelfHostServer可以以控制台程序或windows服务程序为宿主,不单单依赖于IIS web服务器
Self-Hosting ASP.NET Web API http://theshravan.net/self-hosting-asp-net-web-api/ http://www.piotrwal ...
随机推荐
- windows7设置开机启动方式
打开计算机(资源管理器)(快捷键win+e),输入 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup 将需要开机启动的软件的快捷 ...
- 使用php+swoole对client数据实时更新(下)
上一篇提到了swoole的基本使用,现在通过几行基本的语句来实现比较复杂的逻辑操作: 先说一下业务场景.我们目前的大多数应用都是以服务端+接口+客户端的方式去协调工作的,这样的好处在于不论是处在何种终 ...
- python之路十八
1.JS 正则 test - 判断字符串是否符合规定的正则 rep = /\d+/; rep.test("asdfoiklfasdf89asdfasdf ...
- 转:IOC框架
CSND上看了王泽滨的博客关于IOC的,觉得说的很透彻,地址为:http://blog.csdn.net/wanghao72214/article/details/3969594 1 IoC理论的背景 ...
- CentOS7 睡眠 休眠 关机 电源
设置装有 CentOS7 的笔记本合盖后黑屏进入睡眠模式 systemd 能够处理某些电源相关的 ACPI事件,你可以通过从 /etc/systemd/logind.conf 以下选项进行配置: Ha ...
- iOS 对象和json互相转换
// 将字典或者数组转化为JSON串 - (NSData *)toJSONData:(id)theData { NSError *error = nil; NSData *jsonData = [NS ...
- c# 保存数据到txt (追加)
StringBuilder sb = new StringBuilder(); sb.AppendLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:s ...
- File文件的使用
线程的停止: 1.停止一个线程一般是通过一个变量来控制 2.如果需要停止一个处于一个等待状态的线程,那么需要配合interrupture方法来完成 守护线程:(后台线程):在一个进程中只剩下守护线程, ...
- Django框架-目录文件简介
Rhel6.5 Django1.10 Python3.5 Django框架-目录文件简介 1.介绍Django Django:一个可以使Web开发工作愉快并且高效的Web开发框架. 使用Django, ...
- tushare
tushare TuShare是一个免费.开源的python财经数据接口包.主要实现对股票等金融数据从数据采集.清洗加工 到 数据存储的过程,能够为金融分析人员提供快速.整洁.和多样的便于分析的数据, ...