Web API-如何将Controller的返回值转换成HTTP response消息
https://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization
https://code.msdn.microsoft.com/Support-format-in-ASPNET-e3785b2a
1,Web API 框架是一个面向 Http 协议的通信框架。相对于 WCF 而言,Web API 只面向于 Http 协议设计,而且没有 WCF 那么繁琐的配置。
Web API 的开发类似于 ASP.NET MVC 中控制器的开发,但是相对于直接使用 ASP.NET MVC 来返回 Json 对象的方式而言,Web API 封装了数据的序列化、反序列化,接口、实现都更加简单。
简单地说,如果要向浏览器、移动端提供 Json 数据格式的 API,则应该首选 Web API 作为通信框架。,2,Web API 框架目前支持两种数据格式的序列化:Json 及 Xml。在不做任何配置的情况下,如果 Http 请求中,HttpHeader 中 Accept 被指定为 accept: application/xml,则 Web API 会自动把数据使用 xml 进行序列化,否则使用 json 序列化。
如果期望不使用 xml 序列化数据,我们可以通过
GlobalConfiguration.Configuration.Formatters
来进行配置:config.Formatters.Remove(config.Formatters.XmlFormatter)。
一般情况下,我们会使用 Json 序列化。跟 ASP.NET MVC 的 Json 序列化不同的是,Web API 使用了
Newtonsoft.Json 框架来进行序列化。
(例如,JsonMediaTypeFormatter.SerializerSettings
属性就是 Newtonsoft.Json.JsonSerializerSettings 类型,可以直接对序列化进行配置。)
Json 序列化支持对匿名类型进行进行序列化,这大大方便了开发人员,例如,我们可以随意组装数据并直接返回;
Web API 提供了 HttpResponseMessage 类型可作为返回值,使得开发人员可以对 HttpResponse 做一些更详细的设置。而且,如果不期望修改返回值类型而直接返回 HttpResponse 时,可以使用 HttpResponseException 间接返回一个 HttpResponseMessage。
https://www.asp.net/web-api/overview/formats-and-model-binding/content-negotiation
二,Web API-如何将Controller的返回值转换成HTTP response消息
一个Web API 控制器方法可以返回以下类型的值
1.void
2.HttpResponseMessage
3.IHttpActionResult
4.其它一些类型
根据action不同的返回类型,Web API 使用不同的处理方法去创建一个http响应信息。
|
Action返回类型 |
Web API 如何生成响应消息 |
|
void |
返回空 204(No Content) |
|
HttpResponseMessage |
直接转换成HTTP响应消息 |
|
IHttpActionResult |
调用ExecuteAsync方法去创建一个HttpResponseMessage 对象,让后将这个对象转换成Http响应消息 |
|
其他类型 |
将序列化的值写到响应消息的内容中,返回200(OK) |
下面对每一种返回类型做详细说明
void
如果action返回void类型,Web API返回一个空HTTP响应消息,状态码为:204(No Content)
例如:
public class ValuesController : ApiController
{
public void Post()
{
}
}
执行此Action时,响应消息为:
HTTP/1.1 204 No Content Server: Microsoft-IIS/8.0 Date: Mon, 27 Jan 2014 02:13:26 GMT
HttpResponseMessage
如果action返回一个HttpResponseMessage类型值,Web API直接将该对象转换成HTTP响应消息,使用HttpResponseMessage对象的属性值去填充响应消息。
返回HttpResponseMessage类型的方式给了我们更多的控制响应消息的能力,例如下面的控制器 action实现了设置响应消息头Cache-Control 的值
public class ValuesController : ApiController
{
public HttpResponseMessage Get()
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, "value");
response.Content = new StringContent("hello", Encoding.Unicode);
response.Headers.CacheControl = new CacheControlHeaderValue()
{
MaxAge = TimeSpan.FromMinutes(20)
};
return response;
}
}
响应消息:
HTTP/1.1 200 OK Cache-Control: max-age=1200 Content-Length: 10 Content-Type: text/plain; charset=utf-16 Server: Microsoft-IIS/8.0 Date: Mon, 27 Jan 2014 08:53:35 GMT hello
如果你传递一个model 对象(domain model)给CreateResponse方法,Web API将使用媒体格式(media formatter)序列化对象并将序列化后的内容写入到响应主体内容中。
public HttpResponseMessage Get()
{
// Get a list of products from a database.
IEnumerable<Product> products = GetProductsFromDB(); // Write the list to the response body.
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, products);
return response;
}
如上,Web API 将使用请求消息的头部 Accept 指定的格式选择响应消息内容的格式,(内容协商的实现)
IHttpActionResult
IHttpActionResult 接口在Web API2中引入,本质上,它是一个HttpResponseMessage工厂(比如使用NotFound()可以返回404响应,Ok(products)可以返回一个 200响应并返回内容,这两个方法返回的类型均实现了IHttpActionResult接口)。
使用IHttpActionResult 接口有以下几个优势:
--简化控制器的单元测试
--将创建HTTP响应的主要逻辑分离到不同的类中
--通过隐藏创建响应消息的底层细节,使控制器动作的意图更加清晰。
IHttpActionResult 只包含一个方法,ExecuteAsync,这个方法能够异步的创建一个HttpResponseMessage对象。
public interface IHttpActionResult
{
Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
}
如果一个控制器方法返回一个IHttpActionResult类型对象,Web API调用ExecuteAsync方法去创建一个HttpResponseMessage对象,然后将这个对象转换成HTTP响应消息。
可以自己实现IHttpActionResult接口,实现自定义转换方法,比如返回一个纯文本类型响应消息
public class TextResult : IHttpActionResult
{
string _value;
HttpRequestMessage _request; public TextResult(string value, HttpRequestMessage request)
{
_value = value;
_request = request;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage()
{
Content = new StringContent(_value),
RequestMessage = _request
};
return Task.FromResult(response);
}
}
控制器的方法这样写:
public class ValuesController : ApiController
{
public IHttpActionResult Get()
{
return new TextResult("hello", Request);
}
}
这时响应消息为:
HTTP/1.1 200 OK Content-Length: 5 Content-Type: text/plain; charset=utf-8 Server: Microsoft-IIS/8.0 Date: Mon, 27 Jan 2014 08:53:35 GMT hello
通常,你应该将IHttpActionResult接口的实现类定义在System.Web.Http.Results命名空间下,The ApiContoller class defines helper methods that return these built-in action results.(APIController 类定义了返回(这些内建的action返回类型)帮助信息的方法。
在下面的例子中:如果找不到请求的id所对应的产品,控制器则调用APIController.NotFound 去创建一个404(Not Found)响应消息,否则控制器调用APIController.OK,创建一个200(OK)包含产品类容信息的响应消息。
public IHttpActionResult Get (int id)
{
Product product = _repository.Get (id);
if (product == null)
{
return NotFound(); // Returns a NotFoundResult
}
return Ok(product); // Returns an OkNegotiatedContentResult
}
其他的返回类型
对应其他的action返回类型,Web API使用媒体格式(media formatter)序列化返回值,Web API将序列化的值写入肖响应消息的主体中,响应状态代码为200(OK)
public class ProductsController : ApiController
{
public IEnumerable<Product> Get()
{
return GetAllProductsFromDB();
}
}
上面Action返回一个列表类型,如果请求消息中没有指定 Accept头部信息(要求响应消息内容的类型),则会将列表对象序列化成json(默认)返回给浏览器。
返回其他类型的方式,一个缺点就是不能直接返回一个响应错误代码,比如404,当然,可以通过抛出一个HttpResponseException异常来返回响应错误代码,更多信息可查看(Exception Handling in ASP.NET Web API.)
Web API 使用请求消息中 Accept 头部值指定的格式来决定响应消息返回的内容格式(即内容协商方式)
比如:使用Chrome的postman插件

指定请求头部 Accept 值 为:application/xml 则返回xml类型数据。

指定请求头部 Accept 值 为:application/json 则返回json类型数据。
Web API-如何将Controller的返回值转换成HTTP response消息的更多相关文章
- .NetCore Web Api 利用ActionFilterAttribute统一接口返回值格式
.Net Core 同 Asp.Net MVC一样有几种过滤器,这里不再赘述每个过滤器的执行顺序与作用. 在实际项目开发过程中,统一API返回值格式对前端或第三方调用将是非常必要的,在.NetCore ...
- SpringMVC中使用@ResponseBody注解将任意POJO对象返回值转换成json进行返回
@ResponseBody 作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区. ...
- Web API 2:Action的返回类型
Web API 2:Action的返回类型 Web API控制器中的Action方法有如下几种返回类型: void HttpResponseMessage IHttpActionResult 其它类型 ...
- ASP.NET Web API 2:Action的返回类型
Web API控制器中的Action方法有如下几种返回类型: void HttpResponseMessage IHttpActionResult 其它类型 基于上面几种不同的返回类型,Web API ...
- 1.2Web API 2中的Action返回值
本主题描述 ASP.NET Web API 将返回值转换从一个控制器动作到 HTTP 响应消息. 一个 Web API 控制器动作可以返回下列任一操作 ︰ 1.void 2.IHttpActionRe ...
- SpringMVC的@RequestMapping和Controller方法返回值
本节内容: @RequestMapping Controller方法返回值 一.@RequestMapping 通过@RequestMapping注解可以定义不同的处理器映射规则. 1. URL路径映 ...
- SpringMVC入门(二)—— 参数的传递、Controller方法返回值、json数据交互、异常处理、图片上传、拦截器
一.参数的传递 1.简单的参数传递 /* @RequestParam用法:入参名字与方法名参数名不一致时使用{ * value:传入的参数名,required:是否必填,defaultValue:默认 ...
- SpringMVC的Controller的返回值与接收的参数
内容参考自博客: http://blog.csdn.net/u011001084/article/details/52846791 http://blog.csdn.net/xuxiaoyinliu/ ...
- c# 科学计数法值转换成正常值,返回字符串
/// <summary> /// 科学计数法值转换成正常值 /// </summary> /// <param name="value">&l ...
随机推荐
- NOSQL Mongo入门学习笔记 - MongoDB的安装(一)
手上的工作不是很忙,所以来学习学习很久就像接触的MongoDb,无奈前段时间工作时间都比较多.记录在这里供以后参考 环境: Centos 7 64位 开始: 1. 在官网下载Mongo : wget ...
- dtGrid插件集成到Angular环境实现表格化数据展现
00没有抱怨的世界 周末效率好低,两天没更了,看看这看看那,装了个win10发现触摸板驱动不适配,然后找了好久都不行,23333. AngularJS用的时间很短,高级的用法有点吃不消了,$diges ...
- 如何循环遍历document.querySelectorAll()方法返回的结果
使用JavaScript的forEach方法,我们可以轻松的循环一个数组,但如果你认为document.querySelectorAll()方法返回的应该是个数组,而使用forEach循环它: /* ...
- Java在mysql插入数据的时候的乱码问题解决
今天在使用hibernate的时候,插入mysql的数据中的中文总是显示乱码,之前出现过类似的问题,但是没有太在意,今天又发生了.所以向彻底的解决一下. 参考的博文: http://www.cnblo ...
- EasyUI datagrid 分页Json字符串格式
//EasyUI datagrid 分页Json字符串格式 //{"total":xx,"rows":[{...},{...}]} total:总数 rows: ...
- CSRF之攻击与防御
0x01 什么是CSRF攻击 CSRF是Cross Site Request Forgery的缩写(也缩写为XSRF),直译过来就是跨站请求伪造的意思,也就是在用户会话下对某个CGI做一些GET/PO ...
- 转Spring+Hibernate+EHcache配置(二)
Spring AOP+EHCache简单缓存系统解决方案 需要使用Spring来实现一个Cache简单的解决方案,具体需求如下:使用任意一个现有开源Cache Framework,要求可以Cache系 ...
- linux fork函数与vfork函数
一.fork1. 调用方法#include <sys/types.h>#include <unistd.h> pid_t fork(void);正确返回:在父进程中返回子进程的 ...
- 第一章、关于SQL Server数据库的备份和还原(sp_addumpdevice、backup、Restore)
在sql server数据库中,备份和还原都只能在服务器上进行,备份的数据文件在服务器上,还原的数据文件也只能在服务器上,当在非服务器的机器上启动sql server客户端的时候,也可以通过该客户端来 ...
- [Unity菜鸟] Unity鼠标双击,鼠标函数整理(未完)
1. 鼠标双击 void OnGUI() { Event Mouse = Event.current; if (Mouse.isMouse && Mouse.type == Event ...