[ASP.NET MVC2 系列] 
     [ASP.NET MVC2 系列] ASP.Net MVC教程之《在15分钟内用ASP.Net MVC创建一个电影数据库应用程序》 
     [ASP.NET MVC2 系列] ASP.Net MVC教程之《ASP.NET MVC 概述》
     [ASP.NET MVC2 系列] 理解MVC应用程序的执行过程
     [ASP.NET MVC2 系列] ASP.NET MVC Routing概述 
     [ASP.NET MVC2 系列] ASP.NET MVC 之如何创建自定义路由约束 
     [ASP.NET MVC2 系列] Action要求与View本质
     [ASP.NET MVC2 系列] Action Filters以及自定义OutputCache ActionFilterAttribute事件发生次序

创建一个路由约束(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源代码

转载于:https://www.cnblogs.com/jasenkin/archive/2010/08/29/mvc_custom_contraints.html

[ASP.NET MVC2 系列] ASP.NET MVC 之如何创建自定义路由约束相关推荐

  1. 如何将ASP.NET MVC2项目升级到MVC 3 RC

    微软在10号发布了ASP.NET MVC3的发布候选版(RC:Release-candidate),该版本提供了Razor视图引擎的智能感知等功能,并同样具备Online许可.眼馋的同学是不是已经迫不 ...

  2. (翻译)为你的MVC应用程序创建自定义视图引擎

    Creating your own MVC View Engine For MVC Application 原文链接:http://www.codeproject.com/Articles/29429 ...

  3. ASP.NET 5系列教程(七)完结篇-解读代码

     在本文中,我们将一起查看TodoController 类代码. [Route] 属性定义了Controller的URL 模板: [Route("api/[controller]&quo ...

  4. Asp.net MVC2.0系列文章-MVC简介篇

    使用微软VS工具开发Web应用程序主要有两种方式:一种是常用的创建Asp.net Web Forms,另外一种就是今天着重介绍的Asp.net  MVC. <?XML:NAMESPACE PRE ...

  5. [Asp.net MVC]Asp.net MVC5系列——添加数据

    目录 概述 显示添加数据时所用表单 处理HTTP-POST 总结 系列文章 [Asp.net MVC]Asp.net MVC5系列--第一个项目 [Asp.net MVC]Asp.net MVC5系列 ...

  6. Asp.net MVC2.0系列文章-编辑和删除新闻操作

    上一篇文章,我们简单地完成了新闻内容的展示功能(Asp.net MVC2.0系列文章-显示列表和详细页面操作),此篇文章,我们使用Asp.net MVC2.0实现新闻记录的编辑和删除功能. 创建Vie ...

  7. asp.net core 系列 6 MVC框架路由(下)

    一.URL 生成 接着上篇讲MVC的路由,MVC 应用程序可以使用路由的 URL 生成功能,生成指向操作的 URL 链接. 生成 URL 可消除硬编码 URL,使代码更稳定.更易维护. 此部分重点介绍 ...

  8. asp.net core系列 40 Web 应用MVC 介绍与详细示例

    一. MVC介绍 MVC架构模式有助于实现关注点分离.视图和控制器均依赖于模型. 但是,模型既不依赖于视图,也不依赖于控制器. 这是分离的一个关键优势. 这种分离允许模型独立于可视化展示进行构建和测试 ...

  9. Asp.net MVC2.0系列文章-运行Web MVC2.0 Demo

    安装VS2010 首先安装VS2010,安装过程请参考文章: http://www.cnblogs.com/ywqu/archive/2010/01/27/1657450.html. 创建第一个MVC ...

最新文章

  1. 咱们从头到尾说一次 Java 垃圾回收
  2. 【高并发】面试官问我:为啥局部变量是线程安全的?
  3. Deep Residual Learning for Image Recognition 笔记
  4. Apache Camel:基于企业集成模式(EIP)的开源集成框架
  5. Tomcat7调试运行环境搭建与源代码分析入门
  6. ubuntu 14.04 安装Java JDK
  7. rust怎么拆除墙壁指令_人类跌落梦境:城堡怎么过 不少玩家卡在了第六关城堡地图这里...
  8. Gym - 101755G Underpalindromity (树状数组)
  9. 小爱同学100个奇葩回复_小爱同学深度体验报告:这6个问题值得思考
  10. 清除浮动-双伪元素清除浮动(HTML、CSS)
  11. 更改 VSCode 字体
  12. gomarket服务器位置,第一章 昂达V711双核版常见问题解答.pdf
  13. 联想微型计算机ai0,联想baby AI
  14. HDU 3065 病毒侵袭持续中 【AC自动机模版题】
  15. Data Structure - Doubly Linked List (Java)
  16. win 10 安装单点Spark+Hadoop+Python环境
  17. SDN控制器与交换机如何建立连接
  18. 1.CSS3 教程-> 多列布局 > image模块 > cssTransition 过渡 > CSS Animations 动画 > Transform二维
  19. 如何用CSS实现角标
  20. 论文笔记--Self-Supervised Learning of 3D Human Pose using Multi-view Geometry(利用多视角几何学对三维人类姿势进行自我监督学习)

热门文章

  1. 小白都看得懂的监督学习与无监督学习
  2. mysql如果带有换行的处理方式
  3. 【转】python中的对象拷贝
  4. nginx优化-nginx事件处理模型优化use epoll;
  5. MyFaces Tree2控件使用 -----From http://blog.163.com/net_wood/blog
  6. 微信开发学习日记(二):3个案例
  7. python入门常识
  8. 微型php框架 include/mysql.class.php
  9. The following module was built either with optimizations enabled or without debug information - winz
  10. 每个用户做独立的线程同步