使用 ASP.NET Core MVC 创建 Web API——响应数据的内容协商(七)
使用 ASP.NET Core MVC 创建 Web API
使用 ASP.NET Core MVC 创建 Web API(一)
使用 ASP.NET Core MVC 创建 Web API(二)
使用 ASP.NET Core MVC 创建 Web API(三)
使用 ASP.NET Core MVC 创建 Web API(四)
使用 ASP.NET Core MVC 创建 Web API(五)
使用 ASP.NET Core MVC 创建 Web API(六)
ASP.NET Core MVC 包含对通过固定格式或根据客户端规范来设置响应数据格式的内置支持。
ASP.NET Web API的内容协商(Content Negotiation)机制的理想情况是这样的:客户端在请求头的Accept字段中指定什么样的MIME类型,Web API服务端就返回对应的MIME类型的内容(响应头的中Content-Type就是Accept中指定的MIME类型)。而现实情况是,Web API服务端能返回什么MIME类型的响应类型取决于有没有对应这个MIME类型的MediaTypeFormatter。ASP.NET Core Web API的默认提供JsonMediaTypeFormatter,如果要支持 XmlMediaTypeFormatter需要进行配置。
ASP.NET Core MVC 使用的默认格式是 JSON。 内容协商由 ObjectResult 实现。 它还内置于从帮助程序方法(全部基于 ObjectResult)返回的特定于状态代码的操作结果中。 还可以返回一个模型类型(已定义为数据传输类型的类),框架将自动将其打包在 ObjectResult 中。
以下操作方法返回一个对象实例和 NotFound 帮助程序方法:
[HttpGet("{id}")]
public async Task<ActionResult<Book>> GetBookItem(int id)
{
var bookItem = await _context.Book.FindAsync(id);
if (bookItem == null)
{
return NotFound();
}
return bookItem;
}
将返回 JSON 格式的响应,除非请求了另一个格式且服务器可以返回所请求格式。 可以使用 Rester工具创建包括 Accept 标头的请求并指定另一种格式。 在此情况下,如果服务器有可以生成所请求格式的响应的格式化程序,则结果会以服务器首选的格式返回。
1) 在Visual Studio 2017中按F5,启动BookApi应用程序。
2) 打开Firefox浏览器,并打开 Rester,在Reseter中,将 HTTP 方法设置为 GET。
3) 然后在URL输入框中输入要获取的对象URI,例如 http://localhost:5000/api/book/25
4) 选择“Headers”选项卡,选择“Accept”选项,并将值设置为 JSON (application/json)。
5) 使用鼠标点击“Send”按钮。请求将收到具有作书籍数据的“200 正常”响应。如下图。

6) 选择“Headers”选项卡,选择“Accept”选项,并将值设置为 xml (application/xml)。
7) 使用鼠标点击“Send”按钮。请求将收到具有作书籍数据的“200 正常”响应。如下图。我们虽然指定 Accept为 application/xml,但是在默认情况下,ASP.NET Core MVC 仅支持 JSON。所以,即使指定另一种格式,返回的结果仍然是 JSON 格式,而不是我们希望的xml。如下图。

控制器操作可以返回 POCO(普通旧 CLR 对象),在这种情况下,ASP.NET Core MVC 将自动创建打包对象的 ObjectResult。 客户端将获取设有格式的序列化对象(默认为 JSON 格式,可以配置 XML 或其他格式)。 如果返回的对象为 null,那么框架将返回 204 No Content 响应。
1) 在Visual Studio 2017中打开BookController.cs文件,添加以下 GetBook 方法返回实体对象,代码如下:
[HttpGet("{id}")]
public Book GetBook(int id)
{
var bookItem = _context.Book.Find(id);
return bookItem;
}
2)在Visual Studio 2017中按F5启动Web应用程序。
3) 打开浏览器,一并打开Rester。
4) 将 HTTP 方法设置为 GET。将请求 URL 设置为 http://localhost:5000/api/Book/25
5) 使用鼠标点击“Send”按钮。请求将收到具有作书籍数据的“200 正常”响应。如下图。

6) 请求无效将收到“204 无内容”响应。 如下图。

配置格式化程序
如果应用程序需要支持默认 JSON 格式以外的其他格式,那么可以添加 NuGet 包并配置 MVC 来支持它们。输入和输出的格式化程序不同。输入格式化程序由模型绑定使用;输出格式化程序用来设置响应格式。 还可以配置自定义格式化程序。请求头的Accept中除非指定为application/xml或者application/json,否则指定其它任何MIME,
添加 XML 格式支持
在Visual Studio 2017若要添加对 XML 格式的支持,请安装 Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet 包。
1. 在Visual Studio 2017的菜单>工具>选项对话框中,选择“NuGet包管理器”中的常规,根据自己需要,设置默认包管理格式,如下图。

2. 在解决方案资源管理器中,右键单击“引用”,选择“管理 NuGet 程序包”,如下图。

3.将“nuget.org”选择为“包源”,选择“浏览”选项卡并搜索“Microsoft.AspNetCore.Mvc.Formatters.Xml”,在列表中选择该包,然后选择“安装”,如下图。

4.在Visual Studio 2017中打开Startup.cs文件,将 XmlSerializerFormatters 配置添加到 Startup类的ConfigureServices方法中。代码如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BookContext>(options => options.UseSqlServer(Configuration.GetConnectionString("BookContext")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddXmlSerializerFormatters();
}
或者,可以仅添加输出格式化程序:
services.AddMvc(options =>
{
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});
通过上面的代码我们添加了对 XML 格式的支持,控制器方法会基于请求的 Accept 标头返回相应的格式。接下来我们来测试一下。
1) 在Visual Studio 2017中按F5,启动BookApi应用程序。
2) 打开Firefox浏览器,并打开 Rester,在Reseter中,将 HTTP 方法设置为 GET。
3) 选择“Headers”选项卡,选择“Accept”选项,并将值设置为 xml (application/xml)。
4) 使用鼠标左键,单击“SEND”按钮。 响应返回200,响应窗格显示 Content-Type: application/xml 标头,且 Book 对象已序列化为 XML。如下图。

5) 选择“Headers”选项卡,选择“Accept”选项,并将值设置为 JSON (application/json)。
6) 使用鼠标左键,单击“SEND”按钮。 响应返回200,响应窗格显示 Content-Type: application/json 标头,且 Book 对象已序列化为 JSON。如下图。从图片中可以看到请求了设置 Accept: application/json 的标头,且响应也将它指定为其 Content-Type。 BOOK 对象以 JSON 格式显示在响应正文中。

内容协商过程
内容协商仅在 Accept 标头出现在请求中时发生。 请求包含 accept 标头时,框架会以最佳顺序枚举 accept 标头中的媒体类型,并且尝试查找可以生成一种由 accept 标头指定格式的响应的格式化程序。 如果未找到可以满足客户端请求的格式化程序,框架将尝试找到第一个可以生成响应的格式化程序(除非开发人员配置 MvcOptions 上的选项以返回“406 不可接受”)。 如果请求指定 XML,但是未配置 XML 格式化程序,那么将使用 JSON 格式化程序。 一般来说,如果没有配置可以提供所请求格式的格式化程序,那么使用第一个可以设置对象格式的格式化程序。 如果不提供任何标头,则将使用第一个可以处理要返回的对象的格式化程序来序列化响应。 在此情况下,没有任何协商发生 - 服务器确定将使用的格式。
如果 Accept 标头包含 */*,则将忽略该标头,除非 RespectBrowserAcceptHeader 在 MvcOptions 上设置为 true。
使用 ASP.NET Core MVC 创建 Web API——响应数据的内容协商(七)的更多相关文章
- 使用 ASP.NET Core MVC 创建 Web API(五)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
- 使用 ASP.NET Core MVC 创建 Web API(二)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 六.添加数据库上下文 数据库上下文是使用Entity Framewor ...
- 使用 ASP.NET Core MVC 创建 Web API(三)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 十 ...
- 使用 ASP.NET Core MVC 创建 Web API(四)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
- 使用 ASP.NET Core MVC 创建 Web API(六)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
- 使用 ASP.NET Core MVC 创建 Web API(一)
从今天开始来学习如何在 ASP.NET Core 中构建 Web API 以及每项功能的最佳适用场景.关于此次示例的数据库创建请参考<学习ASP.NET Core Razor 编程系列一> ...
- 【ASP.NET Core】设置 Web API 响应数据的格式——FormatFilter特性篇
在上一篇烂文中老周已向各位介绍过 Produces 特性的使用,本文老周将介绍另一个特性类:FormatFilterAttribute. 这个特性算得上是筛选器的马甲,除了从 Attribute 类派 ...
- 使用.Net Core MVC创建Web API
创建.Net Core MVC 打开appsettings.json文件,添加数据库连接 { "Logging": { "LogLevel": { " ...
- 【ASP.NET Core】设置Web API 响应的数据格式——Produces 特性篇
开春首文,今天老周就跟各位大伙伴们聊一个很简单的话题:怎么设定API响应的数据格式. 说本质一点,就是设置所返回内容的 MIME 类型(Content-Type 头).当然了,咱们不会使用在HTTP管 ...
随机推荐
- PAT甲级专题|树的遍历
PAT甲级专题-树的遍历 涉及知识点:树.建树.深度优先搜索.广度优先搜索.递归 甲级PTA 1004 输出每一层的结点,邻接表vector建树后.用dfs.bfs都可以边搜边存当前层的数据, #in ...
- 01-TensorFlow2.0基础
01-TensorFlow基础 Tensorflow是什么 Google的开源软件库 采取数据流图,用于数值计算 支持多种平台 - GPU.CPU. 移动设备 最初用于深度学习,变得越来越通用 Ten ...
- 基于SpringBoot+Netty实现一个自己的推送服务系统
目标 实现一个WebSocket服务中心,支持水平扩展 技术栈 SpringBoot.Netty.JDK8.MySQL.Redis.RabbitMQ.MyBatis-Plus 环境搭建 主要功能点说明 ...
- 第八次作业-非确定的自动机NFA确定化为DFA
NFA 确定化为 DFA 子集法: f(q,a)={q1,q2,…,qn},状态集的子集 将{q1,q2,…,qn}看做一个状态A,去记录NFA读入输入符号之后可能达到的所有状态的集合. 步骤: 1. ...
- 让微信推送Jenkins构建消息
Jenkins作为开发必备之神器,各家大小公司都在使用.Jenkins自身内置了基于邮件推送构建结果的功能.但是随着移动互联网的发展,邮件这玩意已经越来越少使用了,是否有一种办法能把jenkins构建 ...
- J.U.C剖析与解读2(AQS的由来)
J.U.C剖析与解读2(AQS的由来) 前言 前面已经通过实现自定义ReentrantLock与自定义ReentrantReadWriteLock,展示了JDK是如何实现独占锁与共享锁的. 那么实际J ...
- 三菱PLC和卓岚串口服务器使用心得
下面介绍使用FX3u-16M以及卓岚产品ZLAN5103,实现GX Works通过虚拟串口监控PLC 一.PLC通讯口 圆头8孔RS422接口,线序如下: 1.FX3u不同子型号的PLC,引脚定义可能 ...
- 往Github上,上传本地项目
1.先申请一个Github的帐号,创建一个仓库. 复制这个仓库的地址: 创建完空仓库,页面下方会有提示代码,告诉怎么操作 在本地的项目下依次执行下面的代码: git init //在本地创建git ...
- Atmel Studio 7.0 的使用方法
就在最近,Atmel终于推出了新版本IDE——Atmel Studio 7.0,该版本采用了微软最新的 Visual Studio 2015 平台,经过一段时间使用,Atmel Studio 7.0在 ...
- CCF-CSP题解 201912-3 化学方程式
判断化学方程式是否配平. 字符串处理. 有点编译原理递归下降法的感觉. 考场源码,比较粗糙. // INFO BEGIN // // User = 201911513451(陶杨) // Group ...