ASP.NET MVC переназначает значение параметра Catch-All и выполняет другой допустимый маршрут - PullRequest
1 голос
/ 20 августа 2009

Я пытаюсь создать гибкую маршрутизацию URL.

Так что URL вроде

en-US/ctrl/act/1/2

должен сделать то же самое, что и

ctrl/act/1/2

и установите культуру в en-US.

Теперь я достиг этого, определив два маршрута следующим образом:

routes.MapRoute(
    "Ctrl",
    "ctrl/{action}/{group}/{page}",
    new { controller = "Home", action = "Index", group = 1, page = 1 },
    new { group = @"\d+", page = @"\d+" }
    );

routes.MapRoute("CtrlWithCulture",
    "{culture}/ctrl/{action}/{group}/{page}",
    new { culture = "", controller = "Home", action = "Index", group = 1, page = 1 },
    new { culture = "[a-z]{2}-(?:[a-zA-Z]{2,4}-)*(?:[a-zA-Z]{2,4})", group = @"\d+", page = @"\d+" }
    );

У меня есть базовый контроллер, который устанавливает культуру на основе входного параметра. Но я хочу иметь эту функциональность по умолчанию для всех маршрутов, поэтому я попробовал что-то вроде этого.

Global.asax.cs:

routes.MapRoute("RootWithCulture",
    "{culture}/{*rest}",
    new { controller = "Home", action = "Index", culture = "" },
    new { culture = "[a-z]{2}-(?:[a-zA-Z]{2,4}-)*(?:[a-zA-Z]{2,4})" }
    );

MyController.cs 

public class MyController : Controller
{
...
    protected override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!String.IsNullOrEmpty(context.RouteData.Values["culture"].ToStringOrNull()))
        {
            this.SetCulture(String.IsNullOrEmpty(context.RouteData.Values["culture"])
            context.RouteData.Values.Remove("culture");
            // I'm stuck here!
            // I want to try other routes and find and execute the right one...

Я не уверен, что будет правильным подходом к этому ...

1 Ответ

1 голос
/ 12 ноября 2009

В итоге я сделал это с помощью пользовательского RoutingModule, который выглядит следующим образом:

public class RewritingRoutingModule : UrlRoutingModule
{
protected string routeNameToRewrite = "rewrite";
public override void PostResolveRequestCache(HttpContextBase context)
{
 RouteData routeData = this.RouteCollection.GetRouteData(context);
 if (routeData != null)
 {
  if (routeData.Values.ContainsKey(routeNameToRewrite))
  {
   // take all route parameters before *rewrite
   IEnumerable<KeyValuePair<string, object>> additionalData = routeData.Values.TakeWhile(item => item.Key != routeNameToRewrite);
   // put route parameter names and values into HttpContextBase.Item collection
   foreach (KeyValuePair<string, object> item in additionalData)
    context.Items.Add(item.Key, item.Value);
   // rewrite the route with *rewrite part only 
   context.RewritePath("~/" + (routeData.Values[routeNameToRewrite] != null ? routeData.Values[routeNameToRewrite].ToString() : ""));
  }
 }
 base.PostResolveRequestCache(context);
}

Я поместил такой маршрут в конце в Global.asax:

routes.MapRoute("RewritingRoute-Culture", "{culture}/{*rewrite}", new { }, new { culture = @"en-US|de-AT" });

Таким образом, если это соответствует, он добавит значения к HttpContextBase.Items, а затем найдет другой маршрут с контроллером и т. Д. И выполнит его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...