【问题标题】:How to have generic routes in ASP.NET MVC, but handle unknown actions?如何在 ASP.NET MVC 中拥有通用路由,但处理未知操作?
【发布时间】:2009-12-21 17:24:18
【问题描述】:

如果我有路线:

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,并且 Home 控制器中不存在 foo 操作,我想将应用程序定向到未找到的 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
);

谢谢。

【问题讨论】:

  • 您是否考虑过使用自定义错误页面,在用户输入无效 URL(以及其他错误)时将其重定向到特定位置? msdn.microsoft.com/en-us/library/h0hfz6fc(VS.71).aspx
  • 是的,我已将其添加到 web.config 中,但愚蠢地将其设置为 RemoteOnly。很抱歉混淆了。这个问题可以结束了。

标签: asp.net asp.net-mvc asp.net-mvc-routing


【解决方案1】:

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

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

【讨论】:

  • 在实践中,我可能会缓存控制器操作集并与缓存集进行匹配。不过,为了简单起见,我将按原样保留实现。
【解决方案2】:

也许我没有正确理解您的问题,但您在问题顶部的路线已经涵盖了您在底部输入的案例。没有必要像那样明确地定义它们。如果他们输入了一个不存在的操作,就会抛出 404 错误。

如果您想在某人匹配有效控制器但未提供有效操作时做一些特别的事情,您可以在您的控制器中覆盖 HandleUnknownError

【讨论】:

    猜你喜欢
    • 2019-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 2011-08-01
    相关资源
    最近更新 更多