为什么这些路线匹配?

时间:2013-11-23 22:33:45

标签: asp.net asp.net-mvc asp.net-routing

以下代码:

 <li>@Html.ActionLink(metaTapp.Nav_About, "Mayla", "About")</li>
                                <li>@Html.ActionLink(metaTapp.Nav_Support, "Support", "About")</li>
                                <li>@Html.ActionLink(metaTapp.Nav_Exchange, "Index", "Exchange")</li>
                                <li>@Html.ActionLink("Post Rfq", "Create", "Rfq")</li>

正在生成以下链接:

   <li><a href="/Upload/Image?action=Mayla&amp;controller=About">About</a></li>
                                <li><a href="/Upload/Image?action=Support&amp;controller=About">Support</a></li>
                                <li><a href="/Upload/Image?action=Index&amp;controller=Exchange">Exchange</a></li>
                                <li><a href="/Upload/Image?action=Create&amp;controller=Rfq">Post Rfq</a></li>

My Global Application Start如下所示:

  protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            UploadRouteConfig.RegisterRoutes(RouteTable.Routes);
            LocalizationConfig.RegisterRoutes(RouteTable.Routes);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());
        }
    }

UploadRouteConfig.RegisterRoutes:

 public static void RegisterRoutes(RouteCollection routes)
    {

        routes.MapRoute("Upload", "Upload/Image", null).RouteHandler = new UploadMvcRouteHandler();
    }

LocalizationConfig.RegisterRoutes

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapRoute(
            "Account", // Route name
            "Account/{action}", // URL with parameters
            new { controller = "Account", action = "Index" } // Parameter defaults
    );

    routes.MapRoute(
      "RfqCategory",
      string.Format("{{{0}}}/Rfq/CategoryFilter/{{category}}", Constants.ROUTE_PARAMNAME_LANG),
      new { controller = "Rfq", action = "CategoryFilter", category = Guid.Empty.ToString() }
    );

    routes.MapRoute(
        Constants.ROUTE_NAME,
        string.Format("{{{0}}}/{{controller}}/{{action}}/{{rfqid}}", Constants.ROUTE_PARAMNAME_LANG),
        new { controller = "About", action = "Home", rfqid = "00000000-0000-0000-0000-000000000000" }
    );
}

RouteConfig.RegisterRoutes:

 public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute("TappDefault", "{controller}/{action}/{id}", new { controller = "About", action = "Home", id = UrlParameter.Optional }
        );

我无法理解上传是如何与所有内容匹配的。如果路线没有从上传/图像开始,它应该落到本地化配置路线?

1 个答案:

答案 0 :(得分:1)

好的,我的问题的简短答案是我在使用RouteLinks时渲染ActionLinks。 ActionLink将根据路由表条目执行匹配,这似乎是我想要的,但因为我使用的是静态URL:

"Upload/Image"

每个网址都匹配。为什么?因为路线不是过滤器。路由通过将提供的路由值与Url的段的参数进行匹配来工作,但是从以下开始:

"Upload/Image"

没有参数,即{controller}然后技术上一切都是匹配。 tyhe pother hand上的RouteLink允许我指定渲染链接时使用的路径:

@Html.RouteLink(
linkText: "route: Home",
routeName: "TappDefault",
routeValues: new {controller="About", action="Home"}
)

...

来自Professional ASP.NET.MVC4(Jon Galloway,Phil Haack,Brad Wilson,K。Scott Allen)

  

Page 232第9章路由:

     

我们假设你在开头添加了以下页面路由   您的路由列表,以便URL / static / url由。处理   page /aspx/SomePage.aspx:

     

routes.MapPageRoute(“new”,“static / url”,“〜/ aspx / SomePage.aspx”);

     

请注意,您不能将此路线放在路线列表的末尾   在RegisterRoutes方法中,因为它永远不会匹配   来电请求。为什么不呢?好吧,请求/ static / url   将与默认路由匹配,永远不会通过   到达新路线的路线列表。因此,你需要   将此路由添加到之前的路由列表的开头   默认路线。

     

注意此问题不适用于使用Web窗体进行路由。在许多情况下,您可能会路由到非ASP.NET MVC路由   处理程序。

     

将此路线移至定义的路线列表的开头似乎   像一个无辜的变化,对吧?对于传入请求,这个   route只会匹配与/ static / url完全匹配的请求   不符合任何其他要求。这正是你想要的。但   生成的URL怎么样?如果你回去看看结果   两次调用Url.RouteLink后,您会发现两个URL都已损坏:

/url?controller=section&action=Index&id=123
     

/static/url?controller=Home&action=Index&id=123
     

这无疑是路由的一种微妙行为   在某种程度上是一种边缘情况,但却是人们遇到的问题   不时。

     

通常,使用“路由”生成URL时,路由值   您提供的用于“填入”所讨论的URL参数   在本章前面。

     

当您拥有包含网址{controller} / {action} / {id}的路线时,您就是   期望在何时提供控制器,动作和id的值   生成一个URL。在这种情况下,因为新路线没有   任何URL参数,它匹配每个URL生成尝试,因为   从技术上讲,“为每个URL参数提供了一个路由值。”它   只是碰巧没有任何URL参数。这就是为什么所有   现有的URL被破坏,因为每次尝试生成一个URL   现在匹配这条新路线。

     

这可能看起来像一个大问题,但是fi x非常简单。使用   所有路线的名称,并始终使用路线名称   生成网址。大多数时候,让路由选择哪个   您想要用来生成URL的路由实际上是留给它的   机会,这不是适合的   强迫控制狂的开发者。生成时   URL,您通常会确切地知道要链接到哪条路线,所以   你也可以用名字来指定它。如果您需要使用   非命名路由,并完全保留URL生成   路由,我们建议编写验证预期的单元测试   应用程序中路由和URL生成的行为。

     

指定路线的名称不仅可以避免歧义,还可以避免歧义   甚至可能会提高一点性能,因为   路由引擎可以直接转到指定的路由并尝试使用   它用于生成URL。

     

在前面的示例中,您生成了两个链接,如下所示   改变问题。我们更改了代码以使用命名参数   明确改变的内容。 @ Html.RouteLink(linkText:“route:   测试“,routeName:”test“,routeValues:new {controller =”section“,   action =“Index”,id = 123})