剖析ASP.NET WebAPI 转化 ActionResult 为 HttpResponse的机制
众所周知,ASP.NET MVC 通过Action接收用户请求,返回的是ActionResult.ActionResult包含很多种类,这里我搜集了一些常见类型的ActionResult及其相关的描述,见下表格,这里需要指出的是ActionResult也是有类的继承体系的,并不是单一的类,稍后会给出ActionResult的继承体系图。
如上所述,众多ActionResult的类型能够根据请求选择合适的返回类型。对于传统的ASP.NET,请求的是物理文件,根据文件后缀去选择相应的HttpHandler进行处理,HttpHandler对于开发者来说相对比较封闭,如果要对请求做额外的处理,需要重写某些方法。现在使用MVC,Action根据请求灵活选择返回的内容和方式,整个控制都交给开发者来做。回到正题,ActionResult的继承体系如下:
从上面的图不难看出,ActionResult只是众多返回类型的根,从ASP.NET MVC 过渡到 ASP.NET WebAPI,对于请求的解析变化不大,变化最大的是返回类型,返回的是Http的一些状态(删除,新建,更新),对于获取对象的方法,通过HttpResponseMessage<T>封装一个对象返回去,这个稍微特殊点。ApiController当然也支持返回对象,通常是程序内部使用。上述情形的代码Demo如下:
1)通过HttpResponseMessage包装的返回对象
public HttpResponseMessage<product> PostProduct(Product product) {this._dbContext.Save(product);var result = new HttpResponseMessage<product>(product, HttpStatusCode.Created);var location = Url.Route(null, new { id = product.ProductID });result.Headers.Location = new Uri(location);return result;
}
2)直接返回实体
public IEnumerable<Product> GetAllProducts()
{ return products;
}
对于WebApi的请求,可以归纳为四类,Create 、 Update 、 Read 、 Delete,下面列举了相关的匹配情况
HTTP 的四个主要方法 (GET, PUT, POST, DELETE) 按照下列方式映射为 CURD 操作:
- GET 用于获取 URI 资源的进行展示, GET 操作不应对服务端有任何影响;
- PUT 用于更新 URI 上的一个资源, 如果服务端允许, PUT 也可以用于新建一个资源;
- POST 用于新建 资源, 服务端在指定的 URI 上创建一个新的对象, 将新资源的地址作为响应消息的一部分返回;
- DELETE 用于删除指定的 URI 资源。
下面有一个实现的例子。
资源新建(Create)
public HttpResponseMessage<product> PostProduct(Product product) {this._dbContext.Save(product);var result = new HttpResponseMessage<product>(product, HttpStatusCode.Created);var location = Url.Route(null, new { id = product.ProductID });result.Headers.Location = new Uri(location);return result;}
资源更新
public HttpResponseMessage PutProduct(int id, Product product) {if (!this._dbContext.Products.Any(p => p.ProductID == id)) {throw new HttpResponseException(HttpStatusCode.NotFound);}product.ProductID = id;this._dbContext.Update(product);return new HttpResponseMessage(HttpStatusCode.OK);}
资源删除
public HttpResponseMessage DeleteProduct(int id) {var product = this._dbContext.Products.FirstOrDefault(p => p.ProductID == id);this._dbContext.Delete(product);return new HttpResponseMessage(HttpStatusCode.NoContent);}
说到这里,可以总结一下WebApi对于返回类型是如何转化为HttpResponse的。
1) Void类型
public class ValuesController : ApiController
{public void Post(){}
}
客户端会收到如下信息
HTTP/1.1 204 No Content
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 02:13:26 GMT
2)HttpResponseMessage
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;}
}
这个请求只是返回了一个状态,大多数时候,我们都是一些内容的。如下:
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;
}
3)IHttpActionResult
这是WebApi2才引入的一个类型,这个接口定义了一个HttpResponseMessage的工厂,使用IHttpActionResult的好处主要有:
* 方便地写单元测试
* 封装了创建HttpResponse的细节
IHttpActionResult包含一个异步方法-ExecuteAsync,该方法创建一个HttpResponseMessage的实例。
public interface IHttpActionResult
{Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken);
}
下面是一个使用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);}
}
4)其他返回类型
public class ProductsController : ApiController
{public IEnumerable<Product> Get(){return GetAllProductsFromDB();}
}
总结:ASP.NET MVC 到ASP.NET Api的过渡有很多值得思考的地方。这篇文章里面借鉴了官方的一些资料和博客园张志敏的部分内容,一并表示感谢。
剖析ASP.NET WebAPI 转化 ActionResult 为 HttpResponse的机制相关推荐
- 深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation)
原文:http://www.cnblogs.com/artech/archive/2007/05/21/753620.html Microsoft 的Visual Studio为我们在应用开发中提供的 ...
- 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi
一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...
- ASP.NET WebApi技术从入门到实战演练
一.课程介绍 曾经有一位不知名的讲师说过这么一句名言: 一门RPC技术不会,那么千万万门RPC技术将都不会!在今天移动互联网的时代,作为攻城师的我们,谁不想着只写一套API就可以让我们的Web, An ...
- ASP.NET WebApi OWIN 实现 OAuth 2.0
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth 允许用户提供一个令牌, ...
- ASP.NET WebApi 基于分布式Session方式实现Token签名认证
一.课程介绍 明人不说暗话,跟着阿笨一起学玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NETWebSer ...
- asp.net webapi 自托管插件式服务(转)
webapi问世已久,稀里糊涂的人哪它都当mvc来使,毕竟已mvc使用级别的经验就可以应对webapi. webapi和mvc在asp.net5时代合体了,这告诉我们,其实 它俩还是有区别的,要不现在 ...
- ASP.NET WebAPI 集成 Swagger 启用 OAuth 2.0 配置问题
在 ASP.NET WebAPI 集成 Swagger 后,由于接口使用了 IdentityServer 做的认证,调试起来很不方便:看了下 Swashbuckle 的文档 ,是支持 OAuth2.0 ...
- 亲手搭建一个基于Asp.Net WebApi的项目基础框架1
目标:教大家搭建一个简易的前后端分离的项目框架. 目录: 1:关于项目架构的概念 2:前后端分离的开发模式 3:搭建框架的各个部分 这段时间比较闲,所以想把之前项目里用到的一些技术写到博客里来,分享给 ...
- 深入剖析ASP.NET的编译原理之二:预编译(Precompilation)
(转载)在本篇文章的第一部分:[原创]深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation),详细讨论了ASP.NET如何进行动态编译的,现在我们来谈谈另外一种重 ...
最新文章
- Datawhale x 科大讯飞 iFLYTEK A.I.开发者大赛重磅开启!
- SIFT原理与源码分析 特征检测 描述子
- centos安装时各个版本的含义
- 泰康人寿信息化三大核心战略:移动优先、数据驱动和云计算
- 微信小程序自定义组件生命周期
- 从文档流角度理解浏览器页面渲染引擎对元素定位的解析
- HashMap的小知识点
- 【语音处理】基于matlab GUI音频信号处理(调音+调速+调频+滤波)(带面板)【含Matlab源码 299期】
- 致经典初选的60首备选篇目_致经典复选诵读题库:英诗选篇学前及小学段60首...
- oracle 九阴真精,《九阴真经》真的很强吗?其实它杂而不精,顶级高手都不愿意用...
- 【口令破解】远程口令破解和本地口令破解(crunch 字典工具和hydra工具)
- 显示器尺寸对照表_电脑液晶屏尺寸如何计算,液晶屏尺寸对照表
- 什么是全栈工程师,为什么全栈开发用Python,Python web全栈开发究竟有多高薪?
- Lattice Diamond 的安装以及license的获取
- 无损音乐播放器,有软件与硬件之分
- 电商产品设计:如何设计产品分销体系
- 口袋里的mini宝贝,西圣Ava蓝牙耳机,百元即可享受好音质耳机
- 463个生活小窍门 找找你需要的!(1-200)
- Python入门-数据库
- 2017百度前端技术学院习题-05