[整理]ASP.NET WEB API 2学习
2015-02-09 12:55 Benoly 阅读(589) 评论(0) 编辑 收藏 举报1 快速入门
入门最好的资料就是看官方的文章介绍和实例,以获得最新的知识的更新。
当然,还有国人翻译的http://aehyok.com/Blog/Detail/67.html
1.1实例
1.1.1初识WEB API 2
http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
和WEB API 相比,结构上大致没什么区别。
1.1.2 Action Results 的改变
http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/action-results
在原有的基础上新增了异步处理机制,对应不同的IHttpActionResult的具体实现。
- void
- HttpResponseMessage
- IHttpActionResult(WEB API 2新增)
- Some other type
1.1.2.1 IHttpActionResult
IHttpActionResult 定义一个用于以异步方式创建 System.Net.Http.HttpResponseMessage 的命令的借口。
在System.Web.Http.Results命名空间(System.Web.Http.dll)下,可以找到一些常用的IHttpActionResult的实现,异步创建不同HttpStatusCode的HttpResponseMessage。
1.1.2.2 ApiController
ApiController类中,也同时也对应新增了返回IHttpActionResult子类的快捷方法,如OK()方法,会返回OKResult对象等。当然,我们也可以自定义实现IHttpActionResult,满足不同的HttpStatusCode的需要。
1.1.3 路由的新增特性
http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
通过新增的RoutePrefixAttribute、RouteAttribute 、IHttpRouteConstraint,可以灵活的配置不同层次的路由及其路由约束,通过直接对外暴露API(无需匹配WebApiConfig里的routetemplate),以满足不同场景下的需要。
1.1.3.1 RoutePrefixAttribute
1.1.3.2 RouteAttribute
1.1.3.3 IHttpRouteConstraint
在System.Web.Http.Routing.Constraints命名空间下,默认提供了一系列的路由约束IHttpRouteConstraint的具体实现,如AlphaRouteConstraint、DateTimeRouteConstraint等。
当然,可以通过自定义路由约束,实现路由匹配。自定义的IHttpRouteConstraint,为了能运行自定义的IHttpRouteConstraint,必须先进行注册,通过HttpConfiguration.MapHttpAttributeRoutes来注册新的特性路由解析器
1.1.3.4 DefaultInlineConstraintResolver
1.1.4 消息管道的变化
1.1.4.1 HttpMessageHandler
1.1.4.2 DelegatingHandler
1.1.4.3 HttpServer
HttpRoutingDispatcher
1.2 了解更多
1.2.1 MSDN
MSDN关于WEB API 2各个方面的官方指导
https://msdn.microsoft.com/zh-cn/library/dn448365(v=vs.108).aspx
1.2.2 HTTP Message Lifecyle
WEB API 2中独立于IIS的消息管道是其整个核心,其整个消息生命周期在该PDF里有非常详细的说明,从图中可以看到在整个消息生命周期里可以自定义扩展的地方,这个是非常重要的,值得关注的。
http://www.asp.net/media/4071077/aspnet-web-api-poster.pdf
http://www.asp.net/web-api/overview/advanced/http-message-handlers
HttpRequestMessage
在System.Net.Http.dll中的HttpRequestMessage类,是对一个实际的HTTP 请求消息(HTTP请求报文)的包装。
HttpRequestMessage包含了HttpContent、HttpHeaders、HttpMethod和Version这几个类型的属性来对应HTTP请求报文的报文主题,报头,HTTP方法和HTTP协议版本(默认http 1.1版本)
还有一个public IDictionary<string, object> Properties { get; }的属性,HTTP 请求的属性集,是非常重要的。在Web API 中,是不存在HttpContext上下文对象的,而类似的上下文对象会被存储在该Properties 属性对象里,还有,RouteData也是。
MS内置的键值主要都在System.Web.Http.Hosting.HttpPropertyKeys类的字段列表中。
HttpRequestContext
这个类就是类似ASP.NET中的HttpContext的类型,在整个消息处理链中,通过存储在前面的HttpRequestMessage对象的Properties的属性列表里,我们可以在消息处理链中的任一Handler中来获取这一上下文对象,通过System.Web.Http.Hosting.HttpPropertyKeys类的键值名称和System.Net.Http.HttpRequestMessageExtensions静态类的多种扩展方法来方便我们访问不同的属性对象。
HttpServer
根据PDF周期里的图所示,由于HttpServer是整个消息处理链的头(HttpMessageHandler链),于是好奇HttpServer是如何被创建的。查看了源码,分2种情况,一种是基于WebHost,另一种基于SelfHost。分别对应的GlobalConfiguration(System.Web.Http.WebHost.dll的System.Web.Http命名空间下)类和WebApiAppBuilderExtensions(System.Web.Http.Owin.dll的Owin命名空间下),可以找到创建HttpServer相关的代码。不过在System.Web.Http.SelfHost.dll 中存在一个HttpSelfHostServer,继承HttpServer的子类。
HttpServer的Initialize方法中,调用 InnerHandler = HttpClientFactory.CreatePipeline(_dispatcher, _configuration.MessageHandlers);来生成整个管道,自此,整个消息管道的头HttpServer、尾HttpRoutingDispatcher和以及整个链HttpMessageHandlers就准备好了。
从静态方法HttpClientFactory.CreatePipeline可以明显看到,整个消息处理HttpMessageHandler列表通过其innerHandler串联起来,成为消息处理链。
HttpRoutingDispatcher
整个消息处理链的尾部,系统自动创建,直接继承HttpMessageHandler,而非DelegatingHandler,通过其SendAsync方法可以发现HttpRequestMessage对象的IHttpRouteData类型的RouteData属性的获取,主要是通过其public IDictionary<string, object> Properties { get; }属性,指定键值获取的。
protected override Task
{
// Lookup route data, or if not found as a request property then we look it up in the route table
IHttpRouteData routeData = request.GetRouteData();
if (routeData == null)
{
routeData = _configuration.Routes.GetRouteData(request);
if (routeData != null)
{
request.SetRouteData(routeData);
}
}
//...
}
从以上的HttpRoutingDispatcher的SendAsync方法代码可以看出,HttpRoutingDispatcher只是一个代理的作用,不做实际的消息处理,
但是会进行路由的匹配,从而找到对应的IHttpRoute对象,并通过调用IHttpRoute对象的Handler属性(HttpMessageHandler类型)来执行最终的消息处理,如果该Handler不存在,则使用HttpRoutingDispatcher类中默认的一个HttpMessageHandler类型的实例defaultHandler来接管处理。
这个defaultHander实际上是HttpControllerDispatcher类型的,同样是直接继承了HttpMessageHandler抽象类,在其重载方法SendAsync中,会创建根据当前路由来创建最映射到的IHttpController对象实例,最终映射到其方法,返回一个请求HttpMessageResponse对象.
HttpControllerDispatcher
该对象是最终Controller选择调度的地方,同时生成HttpControllerContext控制器上下文对象和HttpControllerDescriptor对象,最后执行找到的IHttpController对象的ExecuteAsync方法。
如果该IHttpController创建失败,直接返回NotFound的HttpMessageResponse消息响应对象。
可以看出,HttpControllerDescriptor.CreateController(request)是实际创建IHttpController对象实例的方法。
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpControllerContext controllerContext = null;
//...
HttpControllerDescriptor controllerDescriptor = ControllerSelector.SelectController(request);
//...
IHttpController controller = controllerDescriptor.CreateController(request);
//...
controllerContext = CreateControllerContext(request, controllerDescriptor, controller);
return await controller.ExecuteAsync(controllerContext, cancellationToken);
}
HttpControllerContext
HttpControllerDescriptor
让我们看看HttpControllerDescriptor到底是如何创建最终匹配的IHttpController的,追朔到具体的代码,IHttpControllerActivator,看名字应该是一个根据具体的Controller的Type类型,通过反射创建IHttpController实例的类。
public virtual IHttpController CreateController(HttpRequestMessage request)
{
if (request == null)
{
throw Error.ArgumentNull("request");
}
// Invoke the controller activator
IHttpControllerActivator activator = Configuration.Services.GetHttpControllerActivator();
IHttpController instance = activator.Create(request, this, ControllerType);
return instance;
}
DefaultHttpControllerActivator
追根溯源,到底IHttpController是在哪里生成的,继续在HttpControllerDescriptor.CreateController的方法里查找,
在命名空间System.Web.Http.Dispatcher下,有DefaultHttpControllerActivator类,继承IHttpControllerActivator接口,
因为是用到反射创建Controller,理所当然,有个缓存的私有属性private Tuple<HttpControllerDescriptor, Func
1.3 OWIN
我们可以使用OWIN 自宿主(SelfHost) ASP.NET WebAPI 2应用。
http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api
//TODO
1.4 获取MS的知识更新
channel9会时常更新新的技术教程,正巧发现这2天有WEB API Design的视频更新,目前有6集。
http://channel9.msdn.com/Series/Web-API-Design/01
2.进阶
2.1 通过WEB API 2的源码学习
通过源码学习是最好的方式
http://aspnetwebstack.codeplex.com/
2.2 优秀开源项目的学习
//TODO
3 实际开发
3.1 WCF and ASP.NET Web API
WCF和WEB API的抉择
https://msdn.microsoft.com/en-us/library/jj823172.aspx
3.2 WP移动开发
移动开发是目前整个开发的趋势,迫切地需要开始有针对性的在移动开发方面做一些实践。同时WEB API 又非常适合移动端的数据交互。
要注意的是,必须在window 8操作系统下, 才可以开发WP8.0+应用。
http://www.asp.net/web-api/overview/mobile-clients/calling-web-api-from-a-windows-phone-8-application
http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-leaderboard/?WT.mc_id=zumo_aspnet&rnd=1
http://blogs.msdn.com/b/webdev/archive/2013/07/19/writing-web-api-client-code-for-multiple-platforms-using-portable-libraries.aspx
3.3 WEB API与SignalR
Web API与SignalR一起同为构建Service的框架。Web API负责构建http常规服务,而SingalR主要负责的是构建实时服务,例如股票,聊天室,在线游戏等实时性要求比较高的服务。