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

       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

      

       查看 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 运行路由的时刻就非常晚,如果编写消息处理程序,知道可能无法访问路由信息是很重要的,因为此时路由可能尚未运行。

      

绑定参数

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

       这里提出一个 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,编码主体数据
时间: 2024-11-05 18:45:31

ASP.NET Web API - ASP.NET MVC 4 系列的相关文章

Asp.net MVC 与 Asp.net Web API 区别

Asp.Net Web API VS Asp.Net MVC 1.Asp.net MVC 是用来创建返回视图(Views)与数据的Web应用,而Asp.net Web API是一种简单轻松地成熟的HTTP服务,它只返回数据,不返回视图(Views). 2.Asp.net Web API可以通过.Net Framework来帮助我们构建REST-ful服务,而且他支持内容协商(根据客户端能接受的格式要求,返回相应的JSON,XML,ATOM),同时Asp.net Web API支持自我宿主(sel

既生瑜何生亮?ASP.NET MVC VS ASP.NET Web API

Asp.net MVC 与 Asp.net Web API 区别 在我们开发一些web应用时,我们一样可以在MVC Framework 中使用JsonResult 来返回JSON数据,同样也可以处理一下简单的AJAX请求,那么为何微软又推出Web API这么个东西呢?接下来我们来比较一下.二者(Asp.net MVC 与 Asp.net Web Api)何时用? Asp.Net Web API VS Asp.Net MVC 1.Asp.net MVC 是用来创建返回视图(Views)与数据的We

【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理

参考页面: http://www.yuanjiaocheng.net/webapi/create-crud-api-1-delete.html http://www.yuanjiaocheng.net/webapi/Consume-web-api.html http://www.yuanjiaocheng.net/webapi/mvc-consume-webapi-get.html http://www.yuanjiaocheng.net/webapi/mvc-consume-webapi-po

ASP.NET Web API系列教程(目录)(转)

注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API.这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术.目前,国内对此关注的人似乎还不多,有关ASP.NET Web API的文章也不多见.为此,本人打算对微软ASP.NET Web API官方网站上的一些教程进行翻译,以期让更多的国人了解.学习和使用这项ASP.NET Web API. ASP.NET Web API系列教程目录 Introduction:Wha

Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中]

前言 本来一直参见于微软官网进行学习的, 官网网址http://www.asp.net/web-api.出于自己想锻炼一下学习阅读英文文章的目的,又可以学习下微软新发布的技术,其实也很久了,但自己菜鸟一枚,对自己来说都是新技术了.鉴于以上两个原因,本人打算借助google翻译和有道词典,来翻译学习这个系列,并通过博客园来记录自己的翻译学习过程.由于自己阅读水平的确太菜,在借助工具的情况下,有时候搞出来的也是蹩脚的语句,自己读着都难受,尤其是到了Web API路由的那两篇,所以自己想着是不是有别人

ASP.NET Web API系列教程目录

ASP.NET Web API系列教程目录 Introduction:What's This New Web API?引子:新的Web API是什么? Chapter 1: Getting Started with ASP.NET Web API第1章 ASP.NET Web API入门 Your First Web API (C#)第一个Web API(C#) Deep Dive into Web API深入探讨Web API(这是一个视频教程,本翻译系列略) Pro ASP.NET Web

Asp.net Web Api 设计

目录 Asp.net Web Api 设计[持续更新] 第一部分 基础知识 第一章 因特网.万维网和HTTP协议 1.1 Web体系结构 第二章 Web Api 2.1 什么是Web Api 2.6 Web Api 指南 第三章 Asp.Net Web Api Asp.net Web Api 设计[持续更新] 第一部分 基础知识 第一章 因特网.万维网和HTTP协议 1.1 Web体系结构 Web体系有三个核心概念:资源 .URL和表示.一个资源由一个URI进行标识,而HTTP客户端使用URI就

初试ASP.NET Web API/MVC API(附Demo)

参考页面: http://www.yuanjiaocheng.net/webapi/media-formatter.html http://www.yuanjiaocheng.net/webapi/webapi-filters.html http://www.yuanjiaocheng.net/webapi/create-crud-api-1.html http://www.yuanjiaocheng.net/webapi/create-crud-api-1-get.html http://ww

ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API

本篇尝试在现有的ASP.NET MVC 4 项目上增加使用ASP.NET Web API. 新建项目,选择"ASP.NET MVC 4 Web应用程序". 选择"基本"项目模版. 在Controllers文件夹下添加一个名称为"TestController"的空API控制器. 在引用文件夹中多了以下程序集:System.Web.HttpSystem.Web.Http.WebHostSystem.Net.HttpSystem.Net.Http.Fo