WebApi2官网学习记录---Content Negotiation

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的例子“

 1 public HttpResponseMessage GetProduct(int id)
 2 {
 3     var product = new Product()
 4         { Id = id, Name = "Gizmo", Category = "Widgets", Price = 1.99M };
 5
 6     IContentNegotiator negotiator = this.Configuration.Services.GetContentNegotiator();
 7
 8     ContentNegotiationResult result = negotiator.Negotiate(
 9         typeof(Product), this.Request, this.Configuration.Formatters);
10     if (result == null)
11     {
12         var response = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
13         throw new HttpResponseException(response));
14     }
15
16     return new HttpResponseMessage()
17     {
18         Content = new ObjectContent<Product>(
19             product,                // What we are serializing
20             result.Formatter,           // The media formatter
21             result.MediaType.MediaType  // The MIME type
22         )
23     };
24 }

默认的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。

时间: 2024-07-30 20:32:50

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

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

HttpResponseException 当WebAPI的控制器抛出一个未捕获的异常时,默认情况下,大多数异常被转为status code为500的http response即服务端错误. HttpResonseException是一个特别的情况,这个异常可以返回任意指定的http status code,也可以返回具体的错误信息. 1 public Product GetProduct(int id) 2 { 3 Product item = repository.Get(id); 4 if

WebApi2官网学习记录---BSON

BSON 是轻量级的,能够进行快速查询和高效的解码/编码.BSON方便查询是由于elements的前面都有一个表示长度的字段,所以解释器可以快速跳过这个elements:高效的解码/编码是因为numeric数据直接存储为numbers,不用转为string. 在服务端启用BSON   public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Formatter

WebApi2官网学习记录---Media Formatters

Web API内建支持XML.JSON.BSON.和form-urlencoded的MiME type. 创建的自定义MIME类型要继承一下类中的一个: MediaTypeFormatter 这个类使用异步的读/写方法 BufferedMediaTypeFormatter 这个类继承自MediaTypeFormatter,但它使用同步的读/写方法 自定义一个MIME类型,如下: public class ProductCsvFormatter:BufferedMediaTypeFormatter

WebApi2官网学习记录--- Authentication与Authorization

Authentication(认证)   WebAPI中的认证既可以使用HttpModel也可以使用HTTP message handler,具体使用哪个可以参考一下依据: 一个HttpModel可以检测ASP.NET请求管道中的所有请求,一个message handler仅仅可以检测到被路由到这个WebAPI的请求 可以预先设置message handlers,让特定的route使用指定的authentication scheme Http Module只能在IIS中使用,Message ha

WebApi2官网学习记录---Tracing

安装追踪用的包 Install-Package Microsoft.AspNet.WebApi.Tracing Update-Package Microsoft.AspNet.WebApi.WebHost //-Version指定具体的版本 启用追踪的功能(在WebApiConfig.cs中) public static class WebApiConfig { public static void Register(HttpConfiguration config) { SystemDiagn

WebApi2官网学习记录---Attribute Routing

从WebApi 1迁移到WebAPI 2要改变配置代码如下: WebApi 1: protected void Application_Start() { // WARNING - Not compatible with attribute routing. WebApiConfig.Register(GlobalConfiguration.Configuration); } WebAPI 2: protected void Application_Start() { // Pass a del

树莓派官网学习记录

树莓派官网学习记录 和GPIO Zero 一起开始 我们将做的 树莓派一侧的排针是称为通用输入输出引脚(GPIO) 这些引脚允许树莓派去控制现实中的东西.你能连接元件到这些引脚上:输出设备像能任意被开关的LED(发光二极管):或者是输入设备像能用作触发事件的一个按钮或者传感器,比如当一个按钮被按下的时候,点亮一只LED. 通过使用GPIO Zero 库,你能很容易的控制树莓派的GPIO引脚. 我们将学习的 通过完成这个资源你将学到: 如何将LED和按钮连接到树莓派的GPIO上 如何通过GPIO

WebApi官网学习记录---web api中的路由

如果一条路由匹配,WebAPI选择controller和action通过如下方式: 1.找到controller,将"controller"赋值给{controller}变量 2.寻找action,web api查看http的请求方式,然后寻找一个以对应请求方式开头的action,如Get请求,需要寻找一个名为Get...的action,这种方式仅支持Get,Post,Put和Delete操作. 除了依据Http请求的方式,还可以显示为action指定http method通过Http

4.Knockout.Js官网学习(事件绑定)

前言 click绑定在DOM元素上添加事件句柄以便元素被点击的时候执行定义的JavaScript 函数.大部分是用在button,input和连接a上,但是可以在任意元素上使用. 简单示例 <h2>ClickBind</h2> <div> You've clicked <span data-bind="text: numberOfClicks"></span> times <button data-bind="