1 回答

TA貢獻(xiàn)1810條經(jīng)驗 獲得超4個贊
路由引擎將選擇與提供的URL匹配的第一條路由,并嘗試在該路由中使用路由值。
RouteTable
int caseSwitch = 1;switch (caseSwitch){ case 1: Console.WriteLine("Case 1"); break; case 1: Console.WriteLine("Second Case 1"); break; default: Console.WriteLine("Default case"); break;}
caseSwitch
1
Route
GetRouteData
GetVirtualPath
一組路由值(或 VirtualPath
對象的 GetVirtualPath
)。這表示與請求匹配的路由。 null
..這表明路由與請求不匹配。
Action
RouteTable
Route
RouteTable
RouteValues
null
null
RouteValues
錯誤配置示例
public class RouteConfig{ public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "CustomRoute", url: "{segment1}/{action}/{id}", defaults: new { controller = "MyController", action = "Index", id = UrlParameter.Optional } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }}
CustomRoute
將匹配任何長度為1、2或3段的URL(注意, segment1
是必需的,因為它沒有默認(rèn)值)。 Default
將匹配任何長度為0、1、2或3段的URL。
\Home\About
CustomRoute
RouteValues
segment1 = "Home"
controller = "MyController"
action = "About"
id = {}
About
MyControllerController
Default
修復(fù)配置
選項1:添加一個或多個文字段
public class RouteConfig{ public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "CustomRoute", url: "Custom/{action}/{id}", // Note, leaving `action` and `id` out of the defaults // makes them required, so the URL will only match if 3 // segments are supplied begining with Custom or custom. // Example: Custom/Details/343 defaults: new { controller = "MyController" } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }}
選項2:添加1個或更多RegEx約束
public class RouteConfig{ public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "CustomRoute", url: "{segment1}/{action}/{id}", defaults: new { controller = "MyController", action = "Index", id = UrlParameter.Optional }, constraints: new { segment1 = @"house|car|bus" } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }}
選項3:添加1個或更多自定義約束
public class CorrectDateConstraint : IRouteConstraint{ public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { var year = values["year"] as string; var month = values["month"] as string; var day = values["day"] as string; DateTime theDate; return DateTime.TryParse(year + "-" + month + "-" + day, System.Globalization.CultureInfo.InvariantCulture, DateTimeStyles.None, out theDate); }}public class RouteConfig{ public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "CustomRoute", url: "{year}/{month}/{day}/{article}", defaults: new { controller = "News", action = "ArticleDetails" }, constraints: new { year = new CorrectDateConstraint() } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }}
備選案文4:使 所需段+使段數(shù)與現(xiàn)有路由不匹配
public class RouteConfig{ public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "CustomRoute", url: "{segment1}/{segment2}/{action}/{id}", defaults: new { controller = "MyController" } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }}
CustomRoute
Default
選項5:為自定義行為實現(xiàn)RouteBase(或路由)
RouteBase
public class SubdomainRoute : Route{ public SubdomainRoute(string url) : base(url, new MvcRouteHandler()) {} public override RouteData GetRouteData(HttpContextBase httpContext) { var routeData = base.GetRouteData(httpContext); if (routeData == null) return null; // Only look at the subdomain if this route matches in the first place. string subdomain = httpContext.Request.Params["subdomain"]; // A subdomain specified as a query parameter takes precedence over the hostname. if (subdomain == null) { string host = httpContext.Request.Headers["Host"]; int index = host.IndexOf('.'); if (index >= 0) subdomain = host.Substring(0, index); } if (subdomain != null) routeData.Values["subdomain"] = subdomain; return routeData; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { object subdomainParam = requestContext.HttpContext.Request.Params["subdomain"]; if (subdomainParam != null) values["subdomain"] = subdomainParam; return base.GetVirtualPath(requestContext, values); }}
public class RouteConfig{ public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add(new SubdomainRoute(url: "somewhere/unique")); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }}
注:
這里真正的問題是,大多數(shù)人認(rèn)為他們的路線都應(yīng)該看起來像 Default
路線。收到,粘貼,完成,對吧?不對。
這種方法通常會產(chǎn)生兩個問題:
幾乎所有其他路由都應(yīng)該至少有一個文字段(如果您喜歡這類內(nèi)容,則應(yīng)該有一個約束)。 最符合邏輯的行為通常是使其他路線具有 所需
片段。
另一個常見的誤解是,可選段意味著您可以省略。 任何段,但在現(xiàn)實中,您只能離開最右邊的一段或幾段。
微軟成功地實現(xiàn)了基于路由約定的、可擴(kuò)展的和強(qiáng)大的路由協(xié)議.他們沒能直觀地理解。幾乎每個人第一次嘗試都失敗了(我知道我成功了!)幸運(yùn)的是,一旦你了解了它的工作原理,就不難了。
添加回答
舉報