Может ли мое приложение MVC2 указать ограничения маршрута для параметров строки запроса? - PullRequest
4 голосов
/ 24 ноября 2010

В моем приложении MVC2 используется компонент, который заставляет последующие AJAX-вызовы возвращаться к тому же действию, которое вызывает все виды ненужного доступа к данным и их обработки на сервере. Поставщик компонента предлагает перенаправить эти последующие запросы на другое действие. Последующие запросы отличаются тем, что у них есть конкретная строка запроса, и я хочу знать, могу ли я наложить ограничения на строку запроса в моей таблице маршрутов.

Например, первоначальный запрос приходит с URL-адресом, таким как 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?vendorParam1=blah1&script=blah.js направлялось в действие VendorController.Display ? В конце концов, я бы хотел, чтобы любой URL, строка запроса которого содержит «vendor», был направлен на действие VendorController.Display.

Я понимаю, что первый URL может быть обработан по умолчанию, но как насчет второго? Возможно ли это сделать вообще? После многих проб и ошибок с моей стороны, похоже, что ответ "Нет".

Ответы [ 3 ]

8 голосов
/ 21 февраля 2011

Параметры QueryString можно использовать в ограничениях, хотя по умолчанию это не поддерживается. Здесь вы можете найти статью, описывающую, как реализовать это в 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 голосов
/ 24 ноября 2010

Вам не нужен маршрут для этого.Это уже обрабатывается механизмом связывания модели по умолчанию.Параметры строки запроса будут автоматически привязаны к аргументам действия:

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];
}
0 голосов
/ 05 марта 2011

Это сообщение старое, но вы не можете написать маршрут до маршрута по умолчанию

это только перехватывает маршруты с "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, но я считаю, что это должно работать ?? Из того, что я понимаю, если ограничение не совпадает, маршрут не используется. Так что было бы проверить следующий маршрут. Поскольку ваш следующий маршрут не использует никаких ограничений для аргументов, он должен соответствовать маршруту.

Я попробовал это, и это сработало для меня.

...