代码之家  ›  专栏  ›  技术社区  ›  flipdoubt

我的MVC2应用程序能否在查询字符串参数上指定路由约束?

  •  4
  • flipdoubt  · 技术社区  · 15 年前

    我的MVC2应用程序使用了一个组件,该组件使随后的Ajax调用返回到同一个操作,这将导致服务器上各种不必要的数据访问和处理。组件供应商建议我将这些后续请求重新路由到其他操作。后续请求的不同之处在于它们有一个特定的查询字符串,我想知道是否可以在路由表中对查询字符串施加约束。

    例如,初始请求带有类似 http://localhost/document/display/1 . 这可以由默认路由处理。我想写一个自定义路由来处理URL http://localhost/document/display/1?vendorParam1=blah1&script=blah.js http://localhost/document/display/1?vendorParam2=blah2&script=blah.js 通过在URL中检测“供应商”。

    我尝试了以下方法,但它抛出了 System.ArgumentException: The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character. :

    routes.MapRoute(
       null,
       "Document/Display/{id}?{args}",
       new { controller = "OtherController", action = "OtherAction" },
       new RouteValueDictionary { { "args", "vendor" } });
    

    我可以写一个考虑查询字符串的路由吗?如果没有,你还有其他想法吗?


    更新: 简单地说,我能写路由约束吗? http://localhost/document/display/1 路由到 DocumentController.Display 行动,但是 http://localhost/document/display/1?供应商参数1=blah1&script=blah.js 路由到 VendorController.Display 行动?最后,我希望将查询字符串包含“vendor”的任何URL路由到 供应商控制器显示 行动。

    我知道第一个URL可以用默认路由处理,但是第二个呢?可以这样做吗?在我这方面经历了很多尝试和错误之后,答案似乎是“不”。

    3 回复  |  直到 14 年前
        1
  •  8
  •   Jan Jongboom    14 年前

    查询字符串参数 可以 在约束中使用,尽管默认情况下不支持它。 Here 您可以在ASP.NET MVC 2中找到一篇描述如何实现此功能的文章。

    正如荷兰语所说,这里是实现。添加“IRouteConstraint”类:

    public class QueryStringConstraint : IRouteConstraint 
    { 
        private readonly Regex _regex; 
    
        public QueryStringConstraint(string regex) 
        { 
            _regex = new Regex(regex, RegexOptions.IgnoreCase); 
        } 
    
        public bool Match (HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
        { 
            // check whether the paramname is in the QS collection
            if(httpContext.Request.QueryString.AllKeys.Contains(parameterName)) 
            { 
                // validate on the given regex
                return _regex.Match(httpContext.Request.QueryString[parameterName]).Success; 
            } 
            // or return false
            return false; 
        } 
    }
    

    现在您可以在您的路线中使用此功能:

    routes.MapRoute("object-contact", 
        "{aanbod}", 
        /* ... */, 
        new { pagina = new QueryStringConstraint("some|constraint") });
    
        2
  •  2
  •   Darin Dimitrov    15 年前

    你不需要这样的路线。它已经由默认的模型绑定器处理。查询字符串参数将自动绑定到操作参数:

    public ActionResult Foo(string id, string script, string vendorname)
    {
        // the id parameter will be bound from the default route token
        // script and vendorname parameters will be bound from the request string
        ...    
    }
    

    更新:

    如果您不知道将要传递的查询字符串参数的名称,可以通过它们进行循环:

    foreach (string key in Request.QueryString.Keys)
    {
        string value = Request.QueryString[key];
    }
    
        3
  •  -1
  •   David Freese    14 年前

    这篇文章很旧,但是你不能在默认路线之前写一条路线吗?

    这将只捕获args中带有“vendor”的路由

    routes.MapRoute(
       null,
       "Document/Display/{id}?{args}",
       new { controller = "VendorController", action = "OtherAction" },
       new {args=@".*(vendor).*"}//believe this is correct regex to catch "vendor" anywhere in the args
    

    ;

    这会抓住剩下的

     routes.MapRoute(
           null,
           "Document/Display/{id}?{args}",
           new { controller = "DisplayController", action = "OtherAction" }
        );
    

    还没试过,我是MVC的新手,但我相信这会奏效??据我所知,如果约束不匹配,则不使用路线。所以它会测试下一条路线。由于您的下一个路由没有对args使用任何约束,因此它应该与该路由匹配。

    我试过了,这对我很有用。