RouteBase.GetRouteData如何工作或指针实现模式匹配

时间:2011-07-20 10:02:56

标签: .net asp.net asp.net-mvc-3 pattern-matching

我正在考虑实现一个选项,用于定义我的HttpModule要忽略的特定URL模式。

我希望能够定义“过滤器”,例如:

/Admin/{*}
/Products/{*}/Search

哪个应过滤网址:

http://mysite.com/admin/options
http://mysite.com/products/toys/search

但不过滤掉     http://mysite.com/orders     http://mysite.com/products/view/1

与ASP.NET MVC如何注册与模式匹配的路由大致相同。 我查看了Phil Haack的Route Debugger的源代码,认为它可能会告诉我RouteBase.GetRouteData(..)是如何工作的,但它只是利用它。

我似乎无法找到任何显示此RouteBase.GetRouteData如何实际工作的示例(或找到它的实际源代码)。

如果有人能够指出我正确的方向,那么这个(或模式匹配)通常是如何实现的那样。

P.S:我已经知道我可以使用正则表达式,但希望有一个非常具体的规则集。

1 个答案:

答案 0 :(得分:1)

<强>更新

既然你想编写一个非常接近模仿工作System.Web.Routing的HttpModule,那么也许你应该使用ILSpy并反映程序集并查看它的作用?

原始答案(为子孙后代保留)

目前尚不清楚您是在谈论ASP.NET MVC还是关于Spring MVC或关于Spring.NET对ASP.NET MVC的扩展。如果它是第一个或第三个:

第一个例子:

Admin/{*}

下面的解决方案#1将解决它。对于你的第二个例子:

Products/{*}/Search,解决方案#2将解决它(如果需要验证或确实在那里有效的话)

这两个解决方案是:

  1. 创建接收这些参数的路线(但不对它们做任何事情,或者不要关心它们)
  2. 创建一个ActionFilter,用于检查这些参数的请求(来自路径),然后将其替换为实际存在的参数。
  3. 解决方案1 ​​

    global.asax.cs中的路线部分:

    routes.MapRoute("AdminAnything",
        "Admin/{*anything}",
        new { controller = admin, action = "Show" }
        );
    

    这将导致以下URL解析为Admin控制器中的Show操作(因此忽略输入):

    Admin/Options  
    Admin/Anything-I-Want-here
    

    解决方案2

    现在,第二个更棘手,因为你实际上有一些东西。

    示例输入:

    Product/{*}/Search  
    

    您可以编写一个拦截请求的ActionFilter,查看它,并将该值替换为您想要的任何值。

    首先,必要的路线:

    routes.MapRoute("ProductSearch",
        "Products/{searchType}/Search,
        new { controller = "Products", action = "Search" }
        );
    

    然后你的控制器动作:

    public ActionResult Search(string searchType)
    {
        //do nothing with searchType here.
    }
    

    如果你想用某些内容替换它,你可以在视图中发送一个隐藏的表单字段并在Actionfilter中处理它:

    public class SearchValidationActionFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if(filterContext.ActionParameters.ContainsKey("searchType") && filterContext.HttpContext.Request.Headers["hiddenSearchType"].IsNotNullOrEmpty()))
            {
            var actualSearchType = filterContext.ActionParameters["hiddenSearchType"] as SearchType;
            var searchType = filterContext.ActionParameters["searchType"];
            if (actualSearchType != null)
            {
                if (searchType.IsNullOrEmpty())
            {
                filterContext.Result = new SearchRedirectResult(actualSearchType.Name);
            }
            else if (!actualSearchType.Name.Equals(searchType))
            {
                filterContext.Result = new SearchRedirectResult(actualSearchType.Name,);
            }
            }
        }
            base.OnActionExecuting(filterContext);
        }
    }
    

    基本上,解决方案#2会接收任何内容,并根据隐藏的搜索类型将其传递给实际的搜索类型。