简体   繁体   English

MVC RouteConfig影响了Html.ActionLink()帮助器方法

[英]MVC RouteConfig affected the Html.ActionLink() helper method

In my MVC project, I've Item controller and some actions like Index . 在我的MVC项目中,我具有Item控制器和诸如Index之类的一些动作。

The RouteConfig includes: RouteConfig包括:

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

In some views, I'm using the helper method Html.ActionLink("Items","Index","Item") to create anchors for the index action. 在某些视图中,我使用了辅助方法Html.ActionLink(“ Items”,“ Index”,“ Item”)为索引操作创建定位符。 So the href of the anchor result will be ( /Item/Index ) 因此锚点结果的href将是( / Item / Index

Now, I need to map the following static URL: 现在,我需要映射以下静态 URL:

/IndirectItem/Index / IndirectItem /索引

to the Index action of the Item controller with default parameter ( indirect = true ), so the RouteConfig will be: 到具有默认参数( indirect = true )的Item控制器的Index操作,因此RouteConfig将是:

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

It seems OK and the client requests were mapped correctly , but all anchors resulted from the Html.ActionLink("Items","Index","Item") helper method were mapped to the URL ( /IndirectItem/Index ) instead of ( /Item/Index ). 看来还可以,并且客户端请求已正确映射,但是由Html.ActionLink(“ Items”,“ Index”,“ Item”)帮助方法产生的所有锚都映射到URL( / IndirectItem / Index )而不是( /项目/索引 )。

How can I fix this problem without changing all Html.ActionLink() to Html.RouteLink() or adding another route for the original url ? 如何在不将所有Html.ActionLink()更改为Html.RouteLink()或为原始网址添加其他路由的情况下解决此问题?

Using constraints will be a convenient solution for your problem. 使用约束将是您解决问题的便捷解决方案。

Use the following IndirectItem route instead of yours. 使用以下IndirectItem路由代替您的路由。

routes.MapRoute(
           name: "IndirectItem",
           url: "{staticVar}/{action}",
           defaults: new { controller = "Item", action = "Index", indirect = true},
           constraints: new { staticVar = "IndirectItem" }
        );

and you don't need any change in the Default route. 而且您不需要更改默认路由。

It works fine with me. 它对我来说很好。

You are experiencing this issue because Html.ActionLink uses Routing table for generating URLs and since IndirectItem route is match to Html.ActionLink("Items","Index","Item") (because it has Index action and Item controller specified in both route and action link). 因为Html.ActionLink使用路由表生成URL,并且IndirectItem路由与Html.ActionLink("Items","Index","Item")匹配,所以您遇到了此问题(因为它同时具有Index操作和Item控制器)路线和动​​作链接)。 The resolving done by a first match so the order of routes registration matters 通过首次比赛完成解析,因此路线注册的顺序很重要

By adding DefaultItem route: 通过添加DefaultItem路由:

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

prior to your current routes: 在您当前路线之前:

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

Should fix the issue 应该解决问题

Another option could be creating empty IndirectItem controller that inherits from Item controller: 另一个选择是创建从Item控制器继承的空IndirectItem控制器:

public IndirectItemController : ItemController
{
}

and then changing the route to 然后将路线更改为

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

The answers given by Omar Gohar and Alex Art are misleading. Omar Gohar和Alex Art给出的答案具有误导性。

The problem you are running into is that your route does not match when generating the URL. 您遇到的问题是生成 URL时您的路由不匹配。 This is simply because you have not provided all of the route values to create a match in your ActionLink . 这是因为您没有提供所有路径值来在ActionLink创建匹配项。

@Html.ActionLink("Items", "Index", "Item", new { indirect = true }, null)

If changing your ActionLink declaration is not an option, you can attach your "indirect" metadata to the route using the DataTokens parameter . 如果不能更改ActionLink声明,则可以使用DataTokens参数"indirect"元数据附加到路由。

You use the DataTokens property to retrieve or assign values associated with the route that are not used to determine whether a route matches a URL pattern . 您可以使用DataTokens属性来检索或分配与路由关联的值,这些值不用于确定路由是否与URL模式匹配 These values are passed to the route handler, where they can be used for processing the request. 这些值将传递到路由处理程序,在此可用于处理请求。

routes.MapRoute(
    name: "IndirectItem",
    url: "IndirectItem/Index",
    defaults: new { controller = "Item", action = "Index" }
).DataTokens = new RouteValueDictionary(new { indirect = true });

The bottom line is that RouteValues (which are populated by the defaults if not provided by the URL pattern) are not meant to be used for metadata. 底线是RouteValues (如果URL模式未提供,则由默认值填充)不打算用于元数据。 They are meant to be real data to match to make the URL unique. 它们是要匹配以使URL唯一的真实数据。

Of course, if you are not actually using the indirect route value for anything, you can simply omit it from the route. 当然,如果您实际上并没有使用indirect路由值,则可以从路由中忽略它。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM