开发者

How to have generic routes in ASP.NET MVC, but handle unknown actions?

If I have a route:

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

I want to be able to catch URL's of the form:

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

This obviously works when an action exists within the Home controller that carries the name of the desired URL. If I enter an erron开发者_如何学编程eous URL, such as http://sitename.com/foo, and the foo action does not exist within the Home controller, I would like to direct the application to a 404 page not found, but obviously if I enter foo, it is looking for the foo action within the home controller. Is there any way to remain generic without hardcoding all the subpages into the global.asax. If at all possible, I want to refrain from:

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

Thanks.


Have you tried using a constraint with a single route? This would allow you to match any action that exists on your Home (or other) controller at the top level.

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

Where MatchesHomeControllerConstraint is:

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


Maybe I'm not understanding your question correctly, but the route that you have at the top of your question will already cover the cases you're typing out at the bottom. There is no need to define them explicitly like that. If they type in an action that doesn't exist, a 404 error will be thrown.

If you want to do something special when someone matches a valid controller but doesn't supply a valid action, you can override HandleUnknownError in your controller.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜