Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
414 views
in Technique[技术] by (71.8m points)

asp.net mvc 2 - Can my MVC2 app specify route constraints on Query String parameters?

My MVC2 app uses a component that makes subsequent AJAX calls back to the same action, which causes all kinds of unnecessary data access and processing on the server. The component vendor suggests I re-route those subsequent requests to a different action. The subsequent requests differ in that they have a particular query string, and I want to know whether I can put constraints on the query string in my route table.

For example, the initial request comes in with a URL like http://localhost/document/display/1. This can be handled by the default route. I want to write a custom route to handle URLs like http://localhost/document/display/1?vendorParam1=blah1&script=blah.js and http://localhost/document/display/1?vendorParam2=blah2&script=blah.js by detecting "vendor" in the URL.

I tried the following, but it throws a 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" } });

Can I write a route that takes the query string into account? If not, do you have any other ideas?


Update: Put simply, can I write routing constraints such that http://localhost/document/display/1 is routed to the DocumentController.Display action but http://localhost/document/display/1?vendorParam1=blah1&script=blah.js is routed to the VendorController.Display action? Eventually, I would like any URL whose query string contains "vendor" to be routed to the VendorController.Display action.

I understand the first URL can be handled by the default route, but what about the second? Is it possible to do this at all? After lots of trial and error on my part, it looks like the answer is "No".

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

QueryString parameters can be used in constraints, although it's not supported by default. Here you can find an article describing how to implement this in ASP.NET MVC 2.

As it is in Dutch, here's the implementation. Add an 'IRouteConstraint' class:

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; 
    } 
}

Now you can use this in your routes:

routes.MapRoute("object-contact", 
    "{aanbod}", 
    /* ... */, 
    new { pagina = new QueryStringConstraint("some|constraint") });

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...