| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1136 人关注过本帖, 1 人收藏
标题:ASP.NET MVC 之如何创建自定义路由约束
只看楼主 加入收藏
bygg
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:乖乖的心中
等 级:版主
威 望:241
帖 子:13555
专家分:3076
注 册:2006-10-23
结帖率:93.75%
收藏(1)
 问题点数:0 回复次数:1 
ASP.NET MVC 之如何创建自定义路由约束
本文将讲解如何创建一个路由约束以及创建一个自定义路由约束

 创建一个路由约束(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对象处理。

如何创建一个 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之间,此处不再叙述。

(四)最后一步是将所有的联系在一起,使 MVC 应用程序能够运行。这里仅仅是定义一个routes。

程序代码:
namespace MvcAppRouting
{
    // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
    // 请访问 <span style="color: #008000; text-decoration: underline;">http://go.[/color]

    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设置了默认的值,并且增加了一个约束对象。这个约束对象将模式中的参数映射至它的约束实例中,因此这些值能够被验证。

现在我用一个验证的请求模式来运行这个应用程序,展示的页面如下。
图片附件: 游客没有浏览图片的权限,请 登录注册

图片附件: 游客没有浏览图片的权限,请 登录注册


总结:
应该注意约束条件必须继承IRouteConstraint,并且实现Match方法。

《转自独上高楼》
搜索更多相关主题的帖子: MVC 路由 NET 定义 ASP 
2010-09-27 17:53
meixiafeng
Rank: 1
来 自:山东成武
等 级:新手上路
帖 子:28
专家分:3
注 册:2010-10-13
收藏
得分:0 
学习学习
2011-06-03 15:42
快速回复:ASP.NET MVC 之如何创建自定义路由约束
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.047798 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved