问题

怎么样将 Asp.Net Web Api 加入到现有的 Asp.Net MVC 项目中

解决方案

在 Visual Studio 2012 中就已经把 Asp.Net Web Api 自动地整合到了 MVC 项目模板中。自 Visual Studio 2013 以后,创建 ASP.Net Web应用程序使用的是一种新的"One ASP.NET"项目向导,在这里可以选择相应的组件,例如,MVC,Web API,WebForm,等等。"One ASP.NET" 是基于微软统一 ASP.NET平台的概念。如图所示 图1-1

图1-1. "One ASP.NET" 项目向导,在一个项目中使用 MVC 和 Web Api

有意思的是,如果你选择了 Web API 项目模板,MVC 的复选框是自动被选中,因为ASP.NET Web API Help Pages 依赖于 MVC 来提供内容。

你也可以在任何已经存在的 MVC 项目中他通过 NuGet 安装"Install-Package Microsofty.Asp.Net.WebApi"来添加 Web API。

其实,上面两种,在 ASP.NET Web 应用项目中,添加 Web API 的方式是等效的,因为项目向导也仅仅是从NuGet 中安装了 ASP.NET Web API。

工作原理

ASP.NET Web API  的构建围绕着一个叫做 System.Web.IHttpAsyncHandler 的异步 HTTP Handler,如演示清单1-1.Handlers 是 ASP.NET 的主干,就是一些可以拦截和处理发送给服务器的 HTTP 请求以及响应相应的请求给客户端的类。

清单 1-1. IhttpAsyncHandler 的定义

1
2
3
4
5
6
public interface IHttpAsyncHandler : object, IHttpHandler
{
    System.IAsyncResult BeginProcessRequest(HttpContext context, System.AsyncCallback cb,
    object extraData);
    void EndProcessRequest(System.IAsyncResult result);
}

事实上,这个和 ASP.NET MVC 框架的体系结构没有多大的不同,他也是位于 Http Hander 上层。其实,他们的框架都是软件工程中复杂的一部分,和常规的 IHttpHandler 或 IHttpAsyncHandler 没有什么特别之处,也许,以前你就创建过处理各种处理基于 HTTP 的工作。

Web API IHttpAsyncHandler 的大致结构——HttpControllerHandler 和他的公共成员,如清单1-2所示

清单 1-2. HttpControllerHandler 的公共成员

1
2
3
4
5
6
public class HttpControllerHandler : HttpTaskAsyncHandler
{
    public HttpControllerHandler(RouteData routeData);
    public HttpControllerHandler(RouteData routeData, HttpMessageHandler handler);
    public override Task ProcessRequestAsync(HttpContext context);
}

MVC 和 Web API 的主要不同是从版本2开始的。Web API Handler-HttpControllerHandler,是HttpTaskAsyncHandler 的一个子类。在 MVC 的版本中,MvcHandler,实现了接口IHttpAsyncHandler。HttpTaskAsyncHandler是在 .NET 4.5 才有的,而 .NET 4.5 是 Web API 2 才支持。

当在同一个 ASP.NET 进程中运行 MVC 和 Web API 的时候,ASP.NET 使用的是HttpApplication。MapRequestHandler事件来决定哪个 HTTP handler 被翻牌子,来处理请求。在这个阶段,进行路由匹配,请求进入到相应匹配路由的 IRouteHandler。IRouteHandler 的唯一目的就是创建一个可以处理请求的 IHttpHandler。

如果 IRouteHandler 是 HttpControllerRouteHandler(Web API 路由),那么,被选择的 Web API 地址路径的请求将被终结在 HttpControllerRouteHandler。相反的,如果路由处理器是 MvcRouteHandler,那么,MVC 的地址路径由 MvcHandler 接管。

代码演示

这一部分要演示的是,ASP.NET MVC 和ASP.NET Web API 将运行在在同一个进程中,他们可以轻而易举的共享状态,例如,静态对象或者 Global.asax 事件。另外,配置文件 web.config 对于两个框架也是通用的。

清单 1-3 展示了两个Controller,MVC Controller 和 ASP.NET Web API Controller,他们可以在一个ASP.NET Web 应用程序共存。值得注意的是,因为他们在不同的命名空间中,所以他们设置可以使用相同的名称。此外,他们可以根据需要共享同一个 model(DTO),非常完美。

清单 1-3. 简单的 MVC 和 Web API 控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Book
{
    public int Id { getset; }
    public string Author { getset; }
    public string Title { getset; }
    public string Link { getset; }
}
Namespace WebApplication.Controllers.Mvc
{
public class BooksController : Controller
{
public ActionResult Details(int id)
{
var book = Books.List.FirstOrDefault(x => x.Id == id);
if(book == nullreturn new HttpNotFoundResult();
return View(book);
}
}
}
namespace WebApplication.Controllers.WebApi
{
public class BooksController : ApiController
{
public Book GetById(int id)
{
var book = Books.List.FirstOrDefault(x => x.Id == id);
if (book == nullthrow new HttpResponseException(HttpStatusCode.NotFound);
return book;
}
}
}

避免两个框架冲突的关键是谨慎惊醒路由设置,为了方便,默认情况下, ASP.NET Web API 将 /api 占位在 URI 下,这样,所有根级别的 URL 将被 MVC 处理。通常情况下,Web API 路由是被定义在 WebApiConfig静态类中,使用 HttpConfiguration 对象和他的 Route 属性。MVC 的路由被定义在 RouteConfig 静态类中,直接使用 System.Web.RouteCollection。两个框架路由的默认定义显示下,清单 1-4.

清单 1-4. Web API 和 MVC 的默认路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//Web API 路由配置
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
//MVC 路由配置
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

第三部分将专门介绍路由,如清单1-4所示,下面的地址是 ASP.NET 应用程序暴露出来的

    • /api/books/{id} 路由到 ASP.NET Web API

    • /books/details/{id} 路由到 ASP.NET MVC

[水煮 ASP.NET Web API2 方法论](1-1)在MVC 应用程序中添加 ASP.NET Web API的更多相关文章

  1. [水煮 ASP.NET Web API2 方法论](1-2)在 WebForm 应用程序中添加 ASP.NET Web API

    问题 怎么样将 Asp.Net Web Api 加入到 Asp.Net Web From 应用程序中 解决方案 在 Visual Studio 2013 中,创建新的 Web From,可以直接在&q ...

  2. [水煮 ASP.NET Web API2 方法论](3-9)空气路由的设置

    阅读导航 问题 解决方案 工作原理 代码演示 在此解释一下,空气路由,是本人臆想出来,觉着更能表达 IgnoreRoute 的意图,如果看着辣眼睛^^,请见谅. 问题 我们在之定义过集中式路由,集中式 ...

  3. 在ASP.NET MVC应用程序中实现Server.Transfer()类似的功能

    在ASP.NET MVC应用程序中,如果使用Server.Transfer()方法希望将请求转发到其它路径或者Http处理程序进行处理,都会引发“为xxx执行子请求时出错”的HttpException ...

  4. 创建ASP.NET Core MVC应用程序(6)-添加验证

    创建ASP.NET Core MVC应用程序(6)-添加验证 DRY原则 DRY("Don't Repeat Yourself")是MVC的设计原则之一.ASP.NET MVC鼓励 ...

  5. 创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段

    创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段 添加查询功能 本文将实现通过Name查询用户信息. 首先更新GetAll方法以启用查询: public async ...

  6. 创建ASP.NET Core MVC应用程序(4)-添加CRUD动作方法和视图

    创建ASP.NET Core MVC应用程序(4)-添加CRUD动作方法和视图 创建CRUD动作方法及视图 参照VS自带的基架(Scaffold)系统-MVC Controller with view ...

  7. 创建ASP.NET Core MVC应用程序(1)-添加Controller和View

    创建ASP.NET Core MVC应用程序(1)-添加Controller和View 参考文档:Getting started with ASP.NET Core MVC and Visual St ...

  8. visual studio 2010 winform程序不能添加对system.web的引用

    visual studio 2010 winform程序不能添加对system.web的引用[转载] 需要引用到System.Web.发现没有“System.Web”.在通过“浏览”方式,找到该DLL ...

  9. [水煮 ASP.NET Web API2 方法论](1-5)ASP.NET Web API Scaffolding(模板)

    问题 我们想快速启动一个 ASP.NET Web API 解决方案. 解决方案 APS.NET 模板一开始就支持 ASP.NET Web API.使用模板往我们的项目中添加 Controller,在我 ...

随机推荐

  1. redis中如何对 key 进行分类

    因为redis中的 hash是不支持设置过期时间的,如果我们要 设置过期时间,还要分类存储,可以用下面折中的方法 其实就是我们把 key 定义的有规律一些,通过在key的字符串内部 分类,上图只是因为 ...

  2. Codeforces Round #340 (Div. 2) A

    A. Elephant time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...

  3. ZOJ1586:QS Network (最小生成树)

    QS Network 题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1586 Description: In th ...

  4. C#或ASP.NET绘图初探

    C#或ASP.NET的简单绘图 public void ProcessRequest (HttpContext context) { context.Response.ContentType = &q ...

  5. HDU1530 最大团 模板

    Maximum Clique Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  6. Java设计模式の观察者模式(推拉模型)

    目录: 一.观察者定义 二.观察者模式的结构(推模式实现) 三.推模型和拉模型(拉模式实现) 四.JAVA提供的对观察者模式的支持 五.使用JAVA对观察者模式的支持(自带推模式实现实例) 一.观察者 ...

  7. 二叉树系列 - [LeetCode] Symmetric Tree 判断二叉树是否对称,递归和非递归实现

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For e ...

  8. Mysql优化小记1

    在项目开发中,需要写个windows服务从sqlserver复制数据到mysql(5.6.13 Win64(x86_64)),然后对这些数据进行计算分析.每15分钟复制一次,每次复制大概200条数据, ...

  9. 【HMOI】小C的填数游戏 DP+线段树维护

    [题目描述] 一个长为n的序列,每个元素有一个a[i],b[i],a[i]为0||1,每个点和他相邻的两个点分别有两条边,权值为cost1[i],cost2[i],对于每个区间l,r,我们可以给每一个 ...

  10. perl 列出一个目录下的文件的大小

    use strict; use warnings; use Cwd; my $dir = 'd:\\www'; chdir($dir); opendir DIR, $dir or die " ...