zoukankan      html  css  js  c++  java
  • [整理]ASP.NET WEB API 2学习

    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

    http://www.asp.net/web-api/overview/web-api-routing-and-actions/create-a-rest-api-with-attribute-routing

    通过新增的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 SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
    // 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> _fastCache;来尽量减少放射的次数。

    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主要负责的是构建实时服务,例如股票,聊天室,在线游戏等实时性要求比较高的服务。

  • 相关阅读:
    第四次上课 PPT作业
    大道至简 读后感④
    第三次上课 PPT 课后测试
    大道至简 读后感③
    Java 02 课后作业
    Java 多个数字相加算法
    大道至简 读后感②
    wpf控件
    一个简单的prism mef例子
    c#弱事件(weak event)
  • 原文地址:https://www.cnblogs.com/Benoly/p/4283129.html
Copyright © 2011-2022 走看看