如何省略主视图的控制器名称

本文关键字:控制器 何省略 主视图 | 更新日期: 2023-09-27 17:55:24

假设我有这样的结构:

Home/
    Index
    About
Project/
    Index
    Details

如何省略主页视图的控制器名称?

我想写{root}/About而不是{root}/Home/About.
我也想{root}/Project/Details/2工作。

这是我在RegisterRoutes中尝试的:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
    name: "DefaultRoute",
    url: "{controller}/{action}/{id}",
    defaults: new
    {
        controller = "Home",
        action = "Index",
        id = UrlParameter.Optional
    }
);
routes.MapRoute(
    name: "HomeRoute",
    url: "{action}",
    defaults: new
    {
        controller = "Home",
        action = "Index"
    }
);

编辑:我也尝试交换MapRoute呼叫的顺序,但它仍然不起作用。
我需要的是:

{root}/Home/Index         > HomeController.Index
{root}/Home               > HomeController.Index
{root}                    > HomeController.Index
{root}/Home/About         > HomeController.About
{root}/About              > HomeController.About
{root}/Project/Index      > ProjectController.Index
{root}/Project            > ProjectController.Index
{root}/Project/Details/12 > ProjectController.Details

如何省略主视图的控制器名称

只需更改MapRoute调用的顺序:

routes.MapRoute(
    name: "HomeRoute",
    url: "{action}",
    defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

必须最后定义"默认"路由,否则它匹配所有 Url 模式,并且不会评估其他路由。

更新:

根据您的编辑,因为您还希望保留"仅控制器名称"路由。试试这个:

public class ActionExistsConstraint : IRouteConstraint
{
    private readonly Type _controllerType;
    public ActionExistsConstraint(Type controllerType)
    {
        this._controllerType = controllerType;
    }
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        var actionName = values["action"] as string;
        if (actionName == null || _controllerType == null || _controllerType.GetMethod(actionName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.IgnoreCase) == null)
            return false;
        return true;
    }
}

然后:

routes.MapRoute(
    name: "HomeRoute",
    url: "{action}",
    defaults: new { controller = "Home", action = "Index" },
    constraints: new { exists = new ActionExistsConstraint(typeof(HomeController)) }
);

请参阅 MSDN