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

时间:2014-03-31 20:23:47

标签: c# asp.net-mvc

假设我有这种结构:

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

1 个答案:

答案 0 :(得分:5)

只需更改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