本文将讲解如何创建一个路由约束以及创建一个自定义路由约束
创建一个路由约束(C#)
你能够使用路由约束来限制匹配一个特殊路径的浏览器请求。你能够使用一个正则表达式来制定一个路由约束。
例如,假设你已经定义路由如下:
Listing 1 - Global.asax.cs
routes.MapRoute(
"Product",
"Product/{productId}",
new {controller="Product", action="Details"}
);
Listing 1 包含一个命名为Product的路由. 你能够使用这个 Product route来将将浏览器请求映射到ProductController,如下:
Listing 2 - Controllers\ProductController.cs
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class ProductController : Controller
{
public ActionResult Details(int productId)
{
return View();
}
}
}
注意:Details() action 接收一个命名为 productId的单一参数. 这个参数是整型参数.
在Listing 1 will中定义的route将匹配一下的任何一个URLs:
?/Product/23
?/Product/7
遗憾的,这个route也同样匹配以下的URLs:
?/Product/blah
?/Product/apple
因为Details() action预期接收一个整型的参数,当请求中包含的内容不同于整数时,它将导致一个错误。
你真正想要做的,仅仅是匹配包含一个的整数productId的URLs。当你定义一个route时,你能够使用一个限制条件来限制URLs,使它匹配这个route。在Listing 3中,这个route包含一个只匹配整数的正则表达式约束。
Listing 3 - Global.asax.cs
routes.MapRoute(
"Product",
"Product/{productId}",
new {controller="Product", action="Details"},
new {productId = @"\d+" }
);
这个真正表达式约束\d+ 匹配一个或多个整数. 这个约束导致Product route匹配如下的URLs:
?/Product/3
?/Product/8999
但不是如下的URLs:
?/Product/apple
?/Product
这个浏览器请求将被另一个route处理。或者,如果没有匹配的routes, “The resource could not be found ”错误将被返回.
创建一个自定义路由约束 (C#)
演示如何创建一个自定义的路由约束.约束接口中的Match方法如下:
IRouteConstraint.Match Method
bool Match(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection
)
你可以通过实现IRouteConstraint接口来创建一个路径约束,并且通过几个步骤把它添加到你的路径中。IRouteConstraint仅有一个Match方法,它返回一个布尔值。这个布尔值决定该请求是否应该被route对象处理。
如何创建一个ASP.NET MVC应用程序来模拟一个仅仅在视图中显示年份,月份,日期的文章系统,类似于博客系统的路径?
(一)首先,创建一个ArchiveController,它包含一个仅仅显示年份,月份,日期值的Index action 方法。
namespace
MvcAppRouting.Controllers
{
public
class
ArchiveController : Controller
{
//
//
GET: /Archive
public
ActionResult Index(
int
year,
int
month,
int
day)
{
ViewData[
"
Year
"
]
=
year;
ViewData[
"
Month
"
]
=
month;
ViewData[
"
Day
"
]
=
day;
return
View();
}
}
}
(二)创建一个显示数据的view。
<%
@ Page Title
=
""
Language
=
"
C#
"
MasterPageFile
=
"
~/Views/Shared/Site.Master
"
Inherits
=
"
System.Web.Mvc.ViewPage
"
%>
<
asp:Content ID
=
"
Content1
"
ContentPlaceHolderID
=
"
TitleContent
"
runat
=
"
server
"
>
Index
</
asp:Content
>
<
asp:Content ID
=
"
Content2
"
ContentPlaceHolderID
=
"
MainContent
"
runat
=
"
server
"
>
<
h2
>
Index
</
h2
>
<
fieldset
>
<
legend
>
Fields
</
legend
>
<
p
>
Year:
<%=
ViewData[
"
Year
"
]
%>
</
p
>
<
p
>
Month:
<%=
ViewData[
"
Month
"
]
%>
</
p
>
<
p
>
Day:
<%=
ViewData[
"
Day
"
]
%></
p
>
</
fieldset
>
</
asp:Content
>
(三)最主要的步骤,需要创建年份,月份,日期验证的三个分离的约束。它们将在路径定义中应用。以创建一个DayConstraint来开始。
using
System.Web.Routing;
using
System.Globalization;
namespace
MvcAppRouting.RouteConstraints
{
public
class
DayConstraint:System.Web.Routing.IRouteConstraint
{
public
bool
Match(HttpContextBase httpContext, Route route,
string
parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if
((routeDirection
==
RouteDirection.IncomingRequest)
&&
(parameterName.ToLower(CultureInfo.InvariantCulture)
==
"
day
"
))
{
try
{
int
month
=
int
.Parse(values[
"
Month
"
].ToString());
int
day
=
int
.Parse(values[
"
Day
"
].ToString());
if
(month
<=
0
||
month
>
12
)
return
false
;
if
(day
<
1
)
return
false
;
switch
(month)
{
case
1
:
case
3
:
case
5
:
case
7
:
case
8
:
case
10
:
case
12
:
if
(day
<
32
)
return
true
;
break
;
case
2
:
if
(day
<
29
)
return
true
;
break
;
case
4
:
case
6
:
case
9
:
case
11
:
if
(day
<
31
)
return
true
;
break
;
}
}
catch
{
return
false
;
}
}
return
false
;
}
}
}
年份数据限制为1950-2010。同样,月份的值在1-12之间,此处不再叙述,详见源代码。
(四)最后一步是将所有的联系在一起,使ASP.NET MVC 应用程序能够运行。这里仅仅是定义一个routes。
namespace
MvcAppRouting
{
//
注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
//
请访问
http://go.microsoft.com/?LinkId=9394801
public
class
MvcApplication : System.Web.HttpApplication
{
public
static
void
RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute(
"
{resource}.axd/{*pathInfo}
"
);
routes.MapRoute(
"
Default
"
,
//
路由名称
"
{controller}/{action}/{id}
"
,
//
带有参数的 URL
new
{ controller
=
"
Home
"
, action
=
"
Index
"
, id
=
UrlParameter.Optional }
//
参数默认值
);
routes.MapRoute(
"
Archive
"
,
"
archive/{year}/{month}/{day}
"
,
new
{
controller
=
"
Archive
"
,
action
=
"
Index
"
,
year
=
""
,
month
=
""
,
day
=
""
},
new
{
year
=
new
RouteConstraints.YearConstraint(),
month
=
new
RouteConstraints.MonthConstraint(),
day
=
new
RouteConstraints.DayConstraint()
}
);
}
protected
void
Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
}
}
实例中的“archive/{year}/{month}/{day}”模式,像正常的routes一样,同样为route设置了默认的值,并且增加了一个约束对象。这个约束对象将模式中的参数映射至它的约束实例中,因此这些值能够被验证。
现在我用一个验证的请求模式来运行这个应用程序,展示的页面如下。
同样,发送一个archive/2000/2/30这个请求,它是不能通过验证,并且得到一个错误。
总结:
应该注意约束条件必须继承IRouteConstraint,并且实现Match方法。
源代码下载: MvcAppRouting源代码
http://www.cnblogs.com/jasenkin/archive/2010/08/29/1812140.html