输出的数据格式是如何决定的-------Asp.net WebAPI学习笔记(二)
在上一篇文章《路由其实也可以很简单》,我们解决了路由问题,这篇文章,我们来研究剩下的另一个问题,为何我们的方法返回的是一个列表,输出到客户端的时候,变成json呢,大家应该还记得我们上一篇文章ProductsController的代码:
using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http; namespace ProductsApp.Controllers
{
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product { Id = , Name = "Tomato Soup", Category = "Groceries", Price = },
new Product { Id = , Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = , Name = "Hammer", Category = "Hardware", Price = 16.99M }
}; public IEnumerable<Product> GetAllProducts()
{
return products;
} public IHttpActionResult GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
}
在使用默认的约定的路由时,我们输入地址:http://localhost:1111/Products,结果返回的是json字符串。

如果大家有ashx的开发经验,应该知道,如果我们是用ashx开发接口,我们可以指定返回的MIME类型,如:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
}
但我们调用GetAllProducts()时,并未指定返回的类型。既然客户端输出json了,那就是说webapi在后台帮我们做了一些事情。
找到这篇介绍MIME类型的文章时,就有大致的头绪了。
上面这篇文章,我们可以了解到,当客户端发送一个http请求的时候,它可以包括一个Accept标头和正文。Accept标头指明客户端想要服务器端返回哪种MIME类型。MIME类型包括:text/html,image/png,application/json等。MIME类型决定了WebAPI如何序列化和反序列化http的正文(body)。WebAPI内置了XML,JSON,BSON和form-urlencoded data四种格式的支持。原来服务端返回什么,是由客户端的请求决定的!
我们使用PostMan尝试增加Accept标头,MIME类型为application/xml。

可以看到,返回的果然就是XML。但是,还记得我们默认的请求是没有指定MIME类型的,疑问还没解决,只好继续查下去。
答案就在这一篇文章中。当客户端发起http请求时,Accept标头,远比我们想象的复杂,例如,有可能是这样的:
Accept: application/json, application/xml; q=0.9, */*; q=0.1
其中,q是权重因子,0<=q<=1,没有指定的时候,默认值是1。例如上面的application/json,没有指定q值,所以默认是1,相当于application/json;q=1。后面的application/xml,q是0.9,其他*/*是0.1,所以返回次序应该是application/json>application/xml.>*/*。
实际的情况可能更复杂,甚至是可以没有Accept,这时,WebApi就会检查http请求的body,如果body中包含有json格式的数据,那么WebApi可能就会返回json格式的数据。这仅仅是其中一个例子,总之WebApi自有一套匹配最合适的formatter的算法。
简而言之,当发起http请求后,WebApi将会根据传入的http和管道上的formatter进行匹配,得到最适合的formatter。如果一直都找不到适合的formatter,那么,WebAPI会选出第一个能序列化输出对象的formatter进行序列化输出。所以,即使我们明确指定了http请求的MIME对象,也不一定能得到对应的输出类型,因为也要取决于WebApi有没有适合的formatter。例如,我们将accept头的application/xml 改为 application/bson,我们发现,返回的依然是json格式的数据,因为WebApi上并没有注册bson格式的formatter。WebApi只好选择第一个能将结果对象序列化的formatter进行序列化输出,这里,就是使用了json formatter了。
我们打开WebApiConfig.cs文件,增加一行代码,添加对bson格式的支持:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
); //注册bson formatter
config.Formatters.Add(new BsonMediaTypeFormatter()); }
}
重新生成一下,然后使用PostMan访问,得到以下结果:

可见,新注册的formatter生效了。关于bson,大家可参考https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/bson-support-in-web-api-21
但是,我们还是建议大家使用http请求的时候,带有明确的MIME类型,而且这个MIME类型不是乱指定的(例如,你明知他会返回json格式,你硬指定MIME类型是text/html),这样,可以尽量避免WebApi再去检查请求的body,性能上来说,应该会快一点。
于是,有的童鞋自然想到,强制所有输出都是json格式。这可以说,也是一种风格吧。其实作为开发接口的人员,应该对接口十分熟悉,因此,在接口文档清晰指出,Accept标头可以使用哪几种MIME类型即可,并不一定硬要强制所有输出都是json。这样,输出什么类型的数据,就可以由客户端请求自行决定了。
输出的数据格式是如何决定的-------Asp.net WebAPI学习笔记(二)的更多相关文章
- 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换
路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...
- 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)
MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中,一切皆路由,url中是完全拒绝"?"和“&”.对此,我 ...
- [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参
[转]ASP.NET MVC学习系列(二)-WebAPI请求 传参 本文转自:http://www.cnblogs.com/babycool/p/3922738.html ASP.NET MVC学习系 ...
- Asp.Net Core WebApi学习笔记(四)-- Middleware
Asp.Net Core WebApi学习笔记(四)-- Middleware 本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Mid ...
- ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现
ASP.NET MVC 学习笔记-2.Razor语法 1. 表达式 表达式必须跟在“@”符号之后, 2. 代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...
- [ASP.NET MVC] ASP.NET Identity学习笔记 - 原始码下载、ID型别差异
[ASP.NET MVC] ASP.NET Identity学习笔记 - 原始码下载.ID型别差异 原始码下载 ASP.NET Identity是微软所贡献的开源项目,用来提供ASP.NET的验证.授 ...
- ASP.NET MVC学习笔记-----Filter2
ASP.NET MVC学习笔记-----Filter(2) 接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用 ...
- ASP.NET MVC学习笔记-----Filter
ASP.NET MVC学习笔记-----Filter(1) Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter Au ...
- ASP.NET MVC学习笔记-----Filter(2)
接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用,它需要实现IActionFilter接口: public ...
随机推荐
- vue 浏览器页面刷新时执行一段代码
当刷新(浏览器刷新)页面的时候,重置到首页(或其他页面)纯js的是window.onload()但是vue几乎不会用到这个,vue所有的是生命周期那么我们可以根据生命周期来实现这个beforeCrea ...
- css字符串转换为类map对象及反转
存储对象为啥是类map(即:{key:val,...}格式),因为Map对象的val为字符时,无法存储 '('.')' 左右括号,我也很无奈╮(╯▽╰)╭ 解析脚本: <!DOCTYPE htm ...
- 纯css导航栏下划线
.nav-underline > *{/* 指定容器,里面可以是li.span等多样化的元素 */ display: inline-block; margin: -3px; padding: 1 ...
- tomcat优化(转)
tomcat优化 Activiti 分享牛 2017-02-08 1132℃ 本文重点讲解tomcat的优化. 基本优化思路: 1. 尽量缩短单个请求的处理时间. 2. ...
- JS高级-Date- Error-***Function:
1. Date: API: 1. 8个单位: FullYear Month Date Day Hours Minutes Seconds Milliseconds 2. 每 ...
- git版本控制工具的使用(1)。
为了使用. 感谢:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 讲解的很清晰, ...
- php-fpm超时时间设置request_terminate_timeout分析
之前发现一个php配置之后关于返回500和502的问题,今天看到一个兄弟写的非常不错,记录一下. php日志中有一条超时的日志,但是我request_terminate_timeout中设置的是0 ...
- JSON转JS对象,JS对象转JSON
一.从服务端发来的json字符串,怎么才能作为JavaScript对象(JSON对象)在web端调用呢? 1.如果使用jQuery,就很方便了,可以在ajax一系列函数中,把参数Datatype传js ...
- Win7 VS2015环境编译cegui-0.8.5
首先是去官网下载源码与依赖库 http://cegui.org.uk/ 然后得提一下,编译DX11版本带Effects11框架的话会有问题,也就是默认情况编译有问题,这是因为VS2015升级后编译器对 ...
- php $_SERVER中的一些选项说明
1, $_SERVER['SCRIPT_FILENAME'] 和 常量 __FILE__的区别(一般情况下两者的显示相同,都是显示文件的绝对路径,包括文件名,显示的起点是 电脑根目录 /) ①,如果在 ...