zoukankan      html  css  js  c++  java
  • ASP.NET Web API

           Web API 项目是 Windows 通信接口(Windows Communication Foundation,WCF)团队及其用户激情下的产物,他们想与 HTTP 深度整合。WCF 进行 Web 服务编程的迭代是一个抽象事务,主要为了隐藏像传输细节一样的内容。Web API 试图彻底颠覆这一过程,去掉 WCF 中的大部分层,而允许开发人员直接访问 HTTP 编程模型的所有方面。

           ASP.NET MVC 在接收表单数据生成 HTML 方面功能非常强大;ASP.NET Web API 在接收和生成像 JSON 和 XML 等结构化数据方面功能非常强大

           由于 ASP.NET Web API 是另一个全新的框架,本文主要介绍 MVC 和 Web API 之间的异同,以帮助大家决定是否在 MVC 项目中使用 Web API。

     

     

    编写 API 控制器

           使用 Web API 模板添加一个项目,这个模板是唯一一个包含示例 API 控制器的模板。

           Web API 和 MVC 都利用了控制器,它们都拥有将 HTTP 请求映射成控制器操作的概念,但不是使用输出模板和视图引擎渲染结果的 MVC 模式,Web API 直接把结果模型对象作为响应来渲染。

           查看先前模板生成的 Web API 类:

    public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
     
        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }
     
        public void Post([FromBody]string value)
        {
        }
     
        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        // POST api/values
        {
        }
     
        // DELETE api/values/5
        public void Delete(int id)
        {
        }
    }

           这个控制器类和 MVC 模式下的控制器类有以下区别:

    1. 它继承自 ApiController 类。
    2. 控制器中的方法返回的是原始对象,而不是视图,也不是其他辅助操作对象。
    3. MVC 控制器总是根据名称调度操作,Web API 控制器默认根据 HTTP 动词调度操作。

    异步设计:IHttpController

           image

           查看 ApiController,如果与 MVC 的Controller 对比,会发现其中一些概念是相同的,比如控制器上下文、ModelState、Url 辅助方法和 User。但一些概念相似却存在差异,比如 Request 是来自 System.Net.Http 的 HttpRequestMessage 而不是来自 System.Web 的 HttpRequestBase,一些概念是缺失的,比如最显著的 Response 和 ActionResult 的生成方法。

           ApiController 中的 ExecuteAsync 方法是接口 IHttpController 中的方法,顾名思义,它意味着所有 Web API 控制器都是异步设计。这里的管道不同于 ASP.NET,因此也不能访问 Response 对象。

           API 控制器期望返回一个 HttpRequestMessage 类型的对象。HttpRequestMessage 和 HttpResponseMessage 类构成了 System.Net.Http 中 HTTP 支持的基础。这些类的设计不同于 ASP.NET 的核心运行时类,在这个栈的处理方法中,给定一个请求消息,期望返回一个响应消息。System.Net.Http 没有静态方法访问持续请求的信息,这也意味着,不必直接写入响应流,开发人员可以返回一个描述响应的对象,然后在需要时渲染

    传入的操作参数

           为从请求中接收传入的值,可在操作上放置参数,就像 MVC 一样,Web API 框架会自动为这些操作方法提供参数值。不同的是,从 HTTP 主体获取的值和从其他地方(比如 URI)获取的值之间有一条强线strong line)。

           默认情况下,Web API 会假设简单类型(如字符串、日期、时间)的参数是非主体值,而复合类型从主体获取。此外,还有一个额外的限制:只有一个值可以来自主体,并且这个值必须代表整个主体。

           如果传入参数不是主体的一部分,就会由模型绑定系统处理,这里的模型绑定系统与 MVC 的相似。另一方面,传入和输出的主体会被一个“格式器”处理

    操作返回值、错误和异步

           Web API 控制器以操作返回值的方式把值发回客户端,然而,返回响应对象是一个相当低级的操作,所以 Web API 控制器几乎总是返回一个原始对象值或值序列。当操作返回一个原始对象时,Web API 使用称为内容协商(Content Negotiation)的功能把它自动转换成一个符合要求的结构化响应,比如 JSON 和 XML。

    配置 Web API

           可能极想知道控制器上的 Configuration 属性。在传统 ASP.NET 应用程序中,应用程序配置在 Global.asax 中完成,应用程序使用全局状态(包括静态的和线程局部变量)访问请求和应用程序配置。

           Web API 被设计为不具有任何这样的静态全局值,而把它的配置放在 HttpConfiguration 类中。这对应用程序有两方面影响:第一,可在一个应用程序中运行多个 Web API 服务器,因为每个服务器有它自身的非全局配置;第二,可在 Web API 中更方便的运行单元测试和端到端测试。

           配置类可以访问下列项:

    • 路由
    • 为所有请求运行的过滤器
    • 参数绑定规则
    • 读写主体内容使用的默认格式器
    • Web API 使用的默认服务
    • 用户提供的依赖解析器(针对服务和控制器上的 DI)
    • HTTP 消息处理程序
    • 标记是否包含像堆栈跟踪这样的错误细节
    • 可以存放用户定义值的 Properties 袋

           创建和访问这些配置的方式取决于我们如何托管应用程序:在 ASP.NET 内,还是在 WCF 自托管内。

    Web 托管 Web API 的配置

           Web API 的配置代码在文件 WebApiConfig.cs 中,开发人员可以修改这个文件以满足自己应用程序的要求,默认代码仅包含一个路由示例

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

           如果查看 Global.asax 文件,会发现这个函数通过传进 GlobalConfiguration.Configuration 对象来调用,Web 托管的 Web API 仅支持单一服务器和单一配置文件

    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
     
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }

           GlobalConfiguration 类在程序集 System.Web.Http.WebHost.dll 中,它是基础设施的其余部分,用来支持 Web 托管的 Web API

    自托管的 Web API

           与 Web API 一起发布的其他托管是基于 WCF 的自托管。自托管的代码包含在程序集 System.Web.Http.SelfHost.dll 中。

           没有针对自托管的内置项目模板,因为这样没有项目类型限制,当需要使用自托管时,我们就可以使用。我们可能正托管在一个控制台应用程序中,或者在一个 GUI 应用程序内部,甚至在一个 Windows 服务中。

           当使用自托管时,需要正确的创建配置,启动和停止 Web API 服务器。我们需要实例化的配置类是 HttpSelfHostConfiguration,因为它通过要求一个监听的 URL 扩展了基类 HttpConfiguration,正确配置好之后,就会创建一个 HttpSelfHostServer 实例,然后告诉它开始监听。

           下面是自托管启动代码的一个示例片段:

    var config = new HttpSelfHostConfiguration("http://localhost:8080/");
     
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
     
    var server = new HttpSelfHostServer(config);
    server.OpenAsync().Wait();
     
    完成之后,应该关闭服务器:
    server.CloseAsync().Wait();

           如果在控制台应用程序中是自托管,我们应该在 Main 函数中运行这些代码,对于其他应用程序类型的自托管,只需要找到合适位置以运行应用程序的启动和关闭代码即可。

           Web API 的托管系统是可插拔的,这些托管配置独立于托管系统

    向 Web API 添加路由

           Web API 的主要路由注册是 MapHttpRoute 扩展方法,与所有 Web API 配置任务一样,为应用程序的路由配置了 HttpConfiguration 对象。Routes 属性指向 HttpRouteCollection 类的一个实例,而不是 ASP.NET 的 RouteCollection 类实例。Web API 提供了一些直接依赖 ASP.NET 中 RouteCollection 类的 MapHttpRoute 版本,但这些路由只有在自托管时才能使用。为避免 Web API 拥有 ASP.NET 的硬依赖,开发团队采用了 ASP.NET 路由代码的副本并加以修改,把它移植到 Web API,当在自托管环境中运行,Web API 会使用它自己的私有路由代码副本;当应用程序是 Web 托管时,Web API 会使用 ASP.NET 的内置路由引擎,因为它已经连接到了 ASP.NET 请求管道。此时,系统就不只会注册 HttpRoute 对象,也会自动创建封装 Route 对象,并在 ASP.NET 路由引擎中注册这些对象。

          自托管和 Web 托管之间的主要区别在于路由的运转时刻:对于 Web 托管,ASP.NET 运行路由非常早;但在自托管中,Web API 运行路由的时刻就非常晚,如果编写消息处理程序,知道可能无法访问路由信息是很重要的,因为此时路由可能尚未运行。

           image

    绑定参数

           当编写操作方法签名时,来自主体的复杂类型由格式器负责生成;来自非主体的简单类型由模型绑定器负责生成。

           这里提出一个 Web API 的新概念:参数绑定Web API 使用参数绑定器来决定如何为各个参数提供值。特性可以用来影响这个决定,比如 MVC 中的特性 [ModelBinder],但当没有重写方法影响绑定决定时,默认的逻辑使用简单类型和复合类型。参数绑定系统通过查看操作参数,寻找 ParameterBindingAttribute 派生的属性。Web API 中创建有一些这样的特性,如下表,此外,还可以通过在配置文件中注册或者通过编写基于 ParameterBindingAttribute 的特性,来注册不使用模型绑定器和格式器的自定义参数绑定器。

    特  性

    描  述

    ModelBindingAttribute 该特性告诉参数绑定系统使用模型绑定,也就是通过使用注册模型绑定器和值提供器创建值。

    这就是通过简单类型参数的默认绑定逻辑表示的内容。
    FromUriAttribute 该特性是一个专门的 ModelBindingAttribute,它告诉系统只能使用实现了 IUriValueProviderFactory 的值提供器,从而限制值的范围,确保它们只能从 URI 获取。

    开箱即用,路由数据和 Web API 中的查询字符串值提供器实现了这个接口。
    FromBodyAttribute 该特性告诉参数绑定系统使用格式器,也就是通过查找 MediaTypeFormatter 的实现创建值,这里的 MediaTypeFormatter 可以解码主体,从解码主体数据中创建给定类型。

    这就是通过任何复合类型的默认绑定逻辑表示的内容。

           在 MVC 中,所有参数都是通过模型绑定创建,而 Web API 模型绑定的工作方式与 MVC(模型绑定器和提供器,值提供器和工厂)几乎一样,尽管它稍微重构了基于 MVC Futures 中的备用模型绑定系统。针对数组、集合、字典、简单类型甚至复合类型,我们会发现有对应的内置模型绑定器,尽管需要使用特性 [ModelBinder] 来运行这些绑定器。虽然接口有轻微改动,但如果知道如何在 MVC 中编写模型绑定器和值提供器,那么也能为 Web API 做同样的事。

           格式器是 Web API 的新概念。格式器主要负责使用和生成主体内容。可以把它想象成 .NET 中的序列化器(serializers):负责编码和解码,可以把一个对象精确编码到主体,也可以从主体中精确解码一个对象,对象可以包含嵌套对象

           Web API 内部有三种格式器:

    1. 使用 Json.NET 编码和解码 JSON
    2. 使用 DataContractSerializer 编码和解码 XML
    3. 另一种解码表单 URL,编码主体数据
  • 相关阅读:
    JavaScript 获取CSS媒体查询信息
    拖拉事件
    JavaScript 中的正常任务与微任务
    IOS 采用https 协议访问接口
    将类数组 转化为数组
    合并两个数组的方法
    base64转码
    Promise 异步执行的同步操作
    proxy set 拦截
    VIm 一些常用的设置
  • 原文地址:https://www.cnblogs.com/SkySoot/p/5666482.html
Copyright © 2011-2022 走看看