ASP.NET Web API - ASP.NET MVC 4 系列

本文探讨了WebAPI与ASP.NET MVC的区别与联系,重点介绍了WebAPI的特点,如异步设计、参数绑定机制及配置方式等,适用于希望深入了解这两种技术差异的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       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 类:

 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
  

       这个控制器类和 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 中,开发人员可以修改这个文件以满足自己应用程序的要求,默认代码仅包含一个路由示例

 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
  

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

 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
  

       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 实例,然后告诉它开始监听。

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

 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
  

       如果在控制台应用程序中是自托管,我们应该在 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,编码主体数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值