无法在 Razor 下的 ActionLink 中传递本机值,而 POCO 实例运行良好

本文关键字:POCO 实例 运行 本机 Razor 下的 ActionLink | 更新日期: 2023-09-27 18:30:41

首先,我以为我又使用了错误的重载(API 中一个非常常见的问题 - 每个人都会绊倒那个重载)。但你不知道吗?不是这样。我实际上也有 HTML 属性参数,我用智能验证了这是我输入的路由值。

@Html.ActionLink("Poof", "Action", "Home", 10, new { @class = "nav-link" })

尽管如此,下面的接收方法似乎只看到 null 并崩溃,因为它无法从中生成整数。

public ActionResult Record(int count) { ... }

我已经尝试了一些事情:将参数类型更改为 int?字符串(程序停止崩溃,但值仍然为 null)。我已经测试过将传递的值打包为对象(带/不带@)。

@Html.ActionLink("Poof", "Record", "Home", 
  new { count = "bamse" }, 
  new { @class = "nav-link" })

我可以看到生成的锚点将我的值作为查询字符串,因此更改就在那里。但是,我仍然仅在该方法中得到值。

我错过了什么?

奇怪的是,以下内容工作正常。

@Html.ActionLink("Poof", "Record", "Home", 
  new Thing(), 
  new { @class = "nav-link" })
public ActionResult Record(Thing count) { ... }

无法在 Razor 下的 ActionLink 中传递本机值,而 POCO 实例运行良好

您使用

@Html.ActionLink()的重载,该重载期望第 4 个参数的类型为 object 。在内部,该方法通过使用对象中每个属性的.ToString()值生成RouteValueDictionary

在您的情况下,您的"对象"(int)没有属性,因此不会生成路由值,并且 url 将只是/Home/Action(并且您的程序崩溃是因为您的方法需要非空参数)。

例如,如果您将其更改为

@Html.ActionLink("Poof", "Action", "Home", "10", new { @class = "nav-link" })

即引用第 4 个参数,现在将/Home/Action?length=2 URL,因为 typeof string 具有属性length并且值中有 2 个字符。

为了传递本机值,您需要使用以下格式

@Html.ActionLink("Poof", "Action", "Home", new { count = 10 }, new { @class = "nav-link" })

这将生成/Home/Action?count=10(如果您使用 Home/Action/{count} 创建特定的路由定义,则会生成/Home/Action/10

另请注意,在您的情况下传递 POCO 只能正常工作,因为您的 POCO 仅包含值类型属性。例如,如果它还包含一个(比如)public List<int> Numbers { get; set; }的属性,那么创建的 url 将包含?Numbers=System.Collections.Generic.List[int](并且绑定将失败),因此请注意在操作链接中传递复杂对象

很难

说你的代码可能有什么问题,从你的问题中提供的信息,但假设完全默认值(Visual Studio 中新创建的 ASP.NET MVC 应用程序),如果你在~/Views/Home/Index.cshtml中添加以下标记:

Html.ActionLink(
    "Poof", 
    "Record", 
    "Home",
    new { count = "bamse" },
    new { @class = "nav-link" }
)

以及HomeController中的以下操作:

public ActionResult Record(string count)
{
    return Content(count);
}

单击生成的锚点后,将调用正确的操作并将正确的参数传递给它。

生成的标记将如下所示:

<a class="nav-link" href="/Home/Record?count=bamse">Poof</a>

所以我想现在你应该问自己的问题是:我的设置与达林在这里概述的有什么不同?回答这个问题可能是您问题的关键。


更新:

好的,现在你似乎改变了你的问题。您似乎正在尝试将复杂对象传递给控制器操作:

public ActionResult Record(Thing count) { ... }

当然,这并不像您期望的那样有效。因此,请确保在构造定位点时传递要可用的每个属性:

Html.ActionLink(
    "Poof", 
    "Record", 
    "Home",
    new { ThingProp1 = "prop1", ThingProp2 = "prop2" },
    new { @class = "nav-link" }
)

或者,当然,处理这种情况的更好方法是将唯一标识符归因于模型,以便从后端检索此模型所需的只是此标识符:

Html.ActionLink(
    "Poof", 
    "Record", 
    "Home",
    new { id = "123" },
    new { @class = "nav-link" }
)

然后在控制器操作中,只需使用此标识符即可检索Thing

public ActionResult Record(int id) 
{
    Thing model = ... fetch the Thing using its identifier
}