如何在 ASP.NET MVC 中拥有通用路由,但处理未知操作?

发布于 2024-08-16 09:36:37 字数 1284 浏览 7 评论 0原文

如果我有一条路线:

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,它会在 Home 控制器中寻找 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
);

谢谢。

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 erroneous 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤蝉 2024-08-23 09:36:37

您是否尝试过对单个路线使用约束?这将允许您匹配顶层家庭(或其他)控制器上存在的任何操作。

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

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) );
     }
}
赠佳期 2024-08-23 09:36:37

也许我没有正确理解你的问题,但是你问题顶部的路线已经涵盖了你在底部输入的情况。没有必要像这样明确地定义它们。如果他们输入不存在的操作,则会抛出 404 错误。

如果您想在某人匹配有效控制器但未提供有效操作时执行一些特殊操作,您可以重写控制器中的 HandleUnknownError

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文