C# 自定义Url路由

C# 自定义Url路由,c#,asp.net-mvc,asp.net-mvc-4,asp.net-mvc-routing,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} ); 对于默认值 routes.MapRoute( name: "Default", url: "{contr

对于
www.demo.com/city/hotel in city

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

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
但是,当我调用home controller的index方法
www.demo.com/home/index
时,它指向第1条路径(默认控制器的index方法)

如何处理默认路由?

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

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,并允许其他所有内容进入搜索


如果您有很多控制器,上述方法可能会不方便。在这种情况下,您可以考虑使用A来过滤默认路由或“搜索”路由,无论您决定在路由配置中首先放置哪个。p> 例如,如果路由引擎试图将“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;
    }
}
这将允许URL从“/Home”开始,一直到默认路由:

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