
正文
[水煮 ASP.NET Web API2 方法论](1-4)从 MVC Controller 链接到 API Controller 以及反向链接
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
问题
想创建一个从 ASP.NET MVC controller 到 ASP.NET Web API controller 的直接链接,或者反向链接。
解决方案
可以使用 System.Web.Http.Routing.UrlHelp 的实例来创建一个指向 Controller的链接,来暴露ApiController(作为 Url 属性)。着和在 RequestContext 上一样,会被附加到 HttpRequestMessage 实例。为了达到这个目的,我们需要调用链接方法或路由方法,然后传入 MVC 路由的名称和默认路由(Controller 名字,Action名字,以及 Action 相关的参数)。
在 MVC Controller 这边,System.Web.Mvc.UrlHelp,挂在基础 MVC 基础 Controller类,可以通过HttpRouteUrl 生成 Web API 链接
工作原理
当使用 ASP.NET Web API 作为现有 MVC 应用程序一部分的时候,有一种很常见的需求,就是在两种类型的Controller 之间可以互相链接。当我们从 Web API 上创建一个到MVC Controller 的链接的时候,实际上使用的方法和创建两个 Web API Controller 之间链接的方法完全相同:UrlHelper 中的链接或者路由。链接和路由生成的链接还是有一些区别的,
-
链接方法将会生成一个绝对链接
-
路由方法生成的是一个相对链接。
反过来,我们从 MVC 链接到 Web API的时候,HttpRouteUrl 并不是 ASP.NET Web API 程序集的扩展方法,而是 UrlHelper 类的成员,在System.Web.Mvc 中。这个 Helper 使用了一个私有的常量叫做 httproute,每次使用 HttpRouteUrl 的时候,他都会被添加到 RouteValueDictionray 中。
注意 我们将会在 3-12 的时候深入学习和理解引擎生成链接到路由背后的故事。
代码演示
假设一个简单的关于书籍的 Web 应用程序。如清单 1-10 所示的简单的 Book 模型,存储使用的是内存, 配置了API/MVC 路由。这个例子的目的是,在 Web API 和 MVC 控制器之间,完美的使用同一个模型。我们将使用在这个清单中的伪数据来说明 Web API 和 MVC 之间互相链接的情况。
清单 1-10. 模型案例,路由和内存存储
|
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
public
class
Book {
public
int
Id {
get
;
set
; }
public
string
Author {
get
;
set
; }
public
string
Title {
get
;
set
; }
public
string
Link {
get
;
set
; }
}
public
static
class
Books {
public
static
List<Book> List =
new
List<Book> {
new
Book {Id = 1, Author =
"John Robb"
, Title =
"Punk Rock: An Oral History"
},
new
Book {
Id = 2,
Author =
"Daniel Mohl"
,
Title =
"Building Web, Cloud, and Mobile Solutions with F#"
},
new
Book {
Id = 3,
Author =
"Steve Clarke"
,
Title =
"100 Things Blue Jays Fans Should Know & Do Before They Die"
},
new
Book {
Id = 4,
Author =
"Mark Frank"
,
Title =
"Cuban Revelations: Behind the Scenes in Havana "
}
};
}
public
class
RouteConfig {
public
static
void
RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute(
"{resource}.axd/{*pathInfo}"
);
routes.MapRoute(
name:
"BookPage"
,
url:
"books/details/{id}"
,
defaults:
new
{controller =
"BooksPage"
, action =
"Details"
}
);
}
}
public
static
class
WebApiConfig {
public
static
void
Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name:
"DefaultApi"
,
routeTemplate:
"api/{controller}/{id}"
,
defaults:
new
{id = RouteParameter.Optional}
);
}
}
|
如清单 1-11 所示,这段代码是为了创建一个从 Web API 到 MVC Controller 的链接。BooksPageController 负责处理书籍。为了生成链接,我们可以调用 UrlHelper 的链接方法,然后传相关路由的值。
清单 1-11 ASP.NET Web API ApiController 链接到 MVC Controller
|
1
2
3
4
5
6
7
8
|
public
class
BooksController : ApiController{
public
Book GetById(
int
id)
{
var
book = Books.List.FirstOrDefault(x => x.Id == id);
if
(book ==
null
)
throw
new
HttpResponseException(HttpStatusCode.NotFound);
book.Link = Url.Link(
"BookPage"
,
new
{controller =
"BooksPage"
, action =
"Details"
, id});
return
book;
}
|
反方向的链接,如清单 1-12 所示,从 MVC Controller 到 ApiController。在这样的情况下,使用一个 MVC 特定的方法-UrlHelper,他是由 HttpRouteUrl 扩展的方法。
清单 1-12. 从 MVC Controller 链接到 ASP.NET Web API
|
1
2
3
4
5
6
7
8
9
|
public
class
BooksPageController : Controller{
public
ActionResult Details(
int
id)
{
var
book = Books.List.FirstOrDefault(x => x.Id == id);
if
(book ==
null
)
return
new
HttpNotFoundResult();
book.Link = Url.HttpRouteUrl(
"DefaultApi"
,
new
{controller =
"Books"
, id});
return
View(book);
}
}
|






