自定义网址路由

时间:2014-02-24 21:29:09

标签: c# asp.net-mvc asp.net-mvc-4 asp.net-mvc-routing

www.demo.com/city/hotel-in-city

routes.MapRoute(
    name: "Search",
    url: "{city}/{slug}",
    defaults: new { controller = "Demo", action = "Index", city = UrlParameter.Optional}
);

default

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

但是当我调用家庭控制器www.demo.com/home/index的索引方法时,它指向第一个路由(默认控制器的索引方法)。

如何处理默认路由?

1 个答案:

答案 0 :(得分:0)

问题在于您的“搜索”路线基本上捕获了所有内容。处理此问题的一种方法是为家庭控制器创建更具体的路由,并将其放在第一位:

routes.MapRoute(
    name: "Home1",
    url: "/",
    defaults: new { action = "Index", controller = "Home" }
);

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

routes.MapRoute(
    name: "Search",
    url: "{city}/{slug}",
    defaults: new { controller = "Demo", action = "Index" }
);

这将过滤掉任何带有“Home”作为第一个参数的URL,并允许其他所有内容进行搜索。


如果您有很多控制器,上述方法可能不方便。在这种情况下,您可以考虑使用custom constraint过滤掉默认路由或“搜索”路由,无论您决定先在路由配置中放置哪一个。

例如,如果路由引擎尝试将“Home”分配给“city”参数,则以下约束声明匹配无效。您可以根据需要对其进行修改,以检查所有控制器,或者根据可用城市名称的缓存列表进行检查:

public class SearchRouteConstraint : IRouteConstraint
{
    private const string ControllerName = "Home";

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        return String.Compare(values["city"].ToString(), ControllerName, true) != 0;
    }
}

这将允许以“/ Home”开头的URL到默认路由:

routes.MapRoute(
    name: "Search",
    url: "{city}/{slug}",
    defaults: new { controller = "Demo", action = "Index" },
    constraints: new { city = new SearchRouteConstraint() }
);

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