ActionLink不能正确处理URL,但RouteLink可以正确处理属性路由

本文关键字:正确处理 属性 RouteLink 路由 不能 URL ActionLink | 更新日期: 2023-09-27 18:14:46

我偶尔会有ActionLink拒绝在我的应用程序中使用占位符生成正确的URL,但是当我在Route属性上指定Name时,它会生成URL属性。

我最近一次遇到这个,来自这个:

[RoutePrefix("RuleConfiguration")]
public class RuleConfigurationController : EntityController<RuleConfigurationModel, RuleConfiguration>
{
    //...Snip...
    [Route("{configurationId}/Edit", Name = "RuleConfigurationEdit")]
    public async Task<ActionResult> Edit(int configurationId)
    {
        return View(...);
    }
    //...Snip...
}

给定此设置,我期望ActionLink,当像这样使用时:

@Html.ActionLink(name, "Edit", "RuleConfiguration", new { configurationId = conf.Id })

给我一个url沿着/RuleConfiguration/1/Edit行。然而,我只得到/RuleConfiguration。当像这样使用RouteLink时:

@Html.RouteLink(conf.Name, "RuleConfigurationEdit", new { configurationId = conf.Id })

生成预期的URL。在同一视图中,我有一个ActionLink生成指向另一个操作的链接,并且该链接使用预期的操作名称生成。唯一不同的是,这个动作没有任何路由参数。

我已经检查了(几次),我有传入的参数ActionLink拼写正确,并且URL参数匹配函数所期望的。RouteName参数被添加,看看RouteLink是否可以工作,ActionLink之前或之后都没有像预期的那样工作。

我是不是错过了什么愚蠢透顶的东西?

ActionLink不能正确处理URL,但RouteLink可以正确处理属性路由

从第一个视图片段开始:

@Html.ActionLink(
    name,
    "Edit",
    "RuleConfiguration",
    new {
        configurationId = conf.Id
    }
)

这个代码片段使用了ActionLink方法的重载:

public static MvcHtmlString ActionLink(
    this HtmlHelper htmlHelper,
    String linkText,
    String actionName,
    Object routeValues,
    Object htmlAttributes
)

这会产生以下HTML:

<a configurationId="1" href="">Hoge</a>

添加configurationId属性到元素中,因为最后一个参数是htmlAttributes参数。

我发现,如果当前的请求已经通过RuleConfigurationController路由,简单地调用下面的似乎工作良好(使用此过载):

@Html.ActionLink(name, "Edit", new { configurationId = 1 })

这会产生以下HTML:

<a href="/RuleConfiguration/1/Edit">Fuga</a>

然而,当试图在不同的控制器中引用一个动作时,这似乎不起作用。


要将重载与希望提供的参数一起使用,请使用以下方法:

public static MvcHtmlString ActionLink(
    this HtmlHelper htmlHelper,
    String linkText,
    String actionName,
    String controllerName,
    Object routeValues,
    Object htmlAttributes
)

如果您不使用htmlAttributes参数,则可以将null传递给它,使您的代码片段变为:

@Html.ActionLink(
    name,
    "Edit",
    "RuleConfiguration",
    new {
        configurationId = conf.Id
    },
    null
)

这将产生预期的锚元素,并且由于指定了控制器名称,因此在引用当前请求没有经过的控制器时也可以工作。