Как иметь общие маршруты в ASP.NET MVC, но обрабатывать неизвестные действия? - PullRequest
0 голосов
/ 21 декабря 2009

Если у меня есть маршрут:

routes.MapRoute(
    "RouteName",                                            // route name
    "{action}",                                             // url with parameters
    new { controller = "Home", action = "Index", id = "" }  // parameter defaults
);

Я хочу, чтобы можно было получать URL-адреса вида:

http://sitename.com/about  
http://sitename.com/contact  
http://sitename.com/others  

Это, очевидно, работает, когда в контроллере Home существует действие, которое содержит имя нужного URL. Если я ввожу ошибочный URL-адрес, такой как http://sitename.com/foo,, и действие foo не существует в контроллере Home, я бы хотел перенаправить приложение на страницу 404, не найденную, но, очевидно, если я введу foo, это будет ищем действие foo в контроллере дома. Есть ли способ остаться универсальным без жесткого кодирования всех подстраниц в global.asax. Если это вообще возможно, я хочу воздержаться от:

routes.MapRoute(
    "About",                                                // route name
    "about",                                                // url with parameters
    new { controller = "Home", action = "About", id = "" }  // parameter defaults
);

routes.MapRoute(
    "Contact",                                                // route name
    "contact",                                                // url with parameters
    new { controller = "Home", action = "Contact", id = "" }  // parameter defaults
);

Спасибо.

Ответы [ 2 ]

2 голосов
/ 21 декабря 2009

Вы пытались использовать ограничение с одним маршрутом? Это позволит вам сопоставить любое действие, которое существует на вашем домашнем (или другом) контроллере на верхнем уровне.

routes.MapRoute(
      "TopLevelGeneric",
      "{action}",
      new { controller = "Home", action = "Index", id = "" },
      new {
              action = new MatchesHomeControllerConstraint()
          });

Где MatchesHomeControllerConstraint:

public class MatchesHomeControllerConstraint : IRouteConstraint
{
     public bool Match( HttpContextBase httpContext, 
                        Route route, 
                        string parameterName, 
                        RouteValueDictionary values, 
                        RouteDirection routeDirection )
     {
           var name = values[parameterName] as string;
           var method =  typeof(HomeController).GetMethod(name,BindingFlags.IgnoreCase);
           return method != null
                  && method.ReturnType.IsAssignableFrom( typeof(ActionResult) );
     }
}
0 голосов
/ 21 декабря 2009

Возможно, я не правильно понимаю ваш вопрос, но маршрут, который вы указали в верхней части вашего вопроса, уже будет охватывать случаи, которые вы вводите внизу. Нет необходимости определять их явно так. Если они введут несуществующее действие, будет выдано сообщение об ошибке 404.

Если вы хотите сделать что-то особенное, когда кто-то соответствует действующему контроллеру, но не предоставляет допустимого действия, вы можете переопределить HandleUnknownError в вашем контроллере.

...