问题

怎么样将 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. SELECT LAST_INSERT_ID() 的使用和注意事项

    SELECT LAST_INSERT_ID() 的使用和注意事项 尊重个人劳动成果,转载请注明出处: http://blog.csdn.net/czd3355/article/details/7130 ...

  2. POJ_2112_Optimal Milking 这里有超级快的网络流板子

    Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among ...

  3. bzoj 1132 [POI2008]Tro 几何

    [POI2008]Tro Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1796  Solved: 604[Submit][Status][Discu ...

  4. Leetcode 557. 反转字符串中的单词 III

    1.题目描述 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode contest" ...

  5. lnmp环境不支持require 解决方法

    lnmp环境配置: 3处改动地方---->排查过程: 从phpinfo.php中查找php.ini-----所在位置 /usr/local/php/etc/php.ini 1.display_e ...

  6. IE8动态创建CSS

    IE8动态创建CSS 最近在项目中用到在页面中动态创建CSS方法,记录一下方便以后查看 一. 在IE下动态创建(网上收集3种方法,最后一个方法未测试成功,具体不知道什么原因) 第一种(此方法很麻烦,需 ...

  7. 图论:Prufer编码

    BZOJ1211:使用prufer编码解决限定结点度数的树的计数问题 首先学习一下prufer编码是干什么用的 prufer编码可以与无根树形成一一对应的关系 一种无根树就对应了一种prufer编码 ...

  8. NDK---使用,开发步骤

    使用NDk的场景: 1.某些方法,是使用C,C++本地代码实现的,然后,我想在Java中调用这些方法.这个时候,就需要使用到JNI技术. 应用NDK的时候,分两个部分,Java部分,JNI层部分,本地 ...

  9. 【洛谷 P3809】 【模板】后缀排序

    题目链接 先占个坑,以后再补. \(SA\)的总结肯定是要写的. 等理解地深入一点再补. #include <cstdio> #include <cstring> const ...

  10. IT培训班123

    最近20年,IT行业一直处于上升期,程序员的工资越来越高了,年薪几十万的程序员大有人在.根据国家统计局发布的2016年各行业平均工资报表,程序员已经是工资最高的一个群体,超过了金融行业. IT行业的火 ...