1 回答
TA贡献1810条经验 获得超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;}caseSwitch1
RouteGetRouteDataGetVirtualPath
一组路由值(或 VirtualPath对象的 GetVirtualPath)。这表示与请求匹配的路由。 null..这表明路由与请求不匹配。
ActionRouteTable
RouteRouteTableRouteValuesnull
nullRouteValues
错误配置示例
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是必需的,因为它没有默认值)。 Default将匹配任何长度为0、1、2或3段的URL。
\Home\AboutCustomRouteRouteValues
segment1 = "Home"controller = "MyController"action = "About"id = {}
AboutMyControllerControllerDefault
修复配置
选项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:使 所需段+使段数与现有路由不匹配
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 }
);
}}CustomRouteDefault
选项5:为自定义行为实现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 }
);
}}注:
这里真正的问题是,大多数人认为他们的路线都应该看起来像 Default路线。收到,粘贴,完成,对吧?不对。
这种方法通常会产生两个问题:
几乎所有其他路由都应该至少有一个文字段(如果您喜欢这类内容,则应该有一个约束)。 最符合逻辑的行为通常是使其他路线具有 所需
片段。
另一个常见的误解是,可选段意味着您可以省略。 任何段,但在现实中,您只能离开最右边的一段或几段。
微软成功地实现了基于路由约定的、可扩展的和强大的路由协议.他们没能直观地理解。几乎每个人第一次尝试都失败了(我知道我成功了!)幸运的是,一旦你了解了它的工作原理,就不难了。
添加回答
举报
