无法在 Razor 下的 ActionLink 中传递本机值,而 POCO 实例运行良好
Unable to pass a native value in ActionLink under Razor while POCO instances work great
首先,我认为我再次使用了错误的重载(API 中一个非常常见的问题 - 每个人都被那个问题绊倒了)。但是你不知道吗?不是这个。我实际上也有 HTML attributes 参数,我用 intellisense 验证这是我输入的路由值。
@Html.ActionLink("Poof", "Action", "Home", 10, new { @class = "nav-link" })
然而,似乎下面的接收方法只能看到 null 并崩溃,因为它无法从中生成整数。
public ActionResult Record(int count) { ... }
我尝试了一些方法:将参数类型更改为 int? 和 string(程序停止崩溃但值为仍然为空)。我已经测试过将传递的值打包为一个对象(with/without @)。
@Html.ActionLink("Poof", "Record", "Home",
new { count = "bamse" },
new { @class = "nav-link" })
我可以看到生成的锚点具有我作为查询字符串的值,所以更改就在那里。但是,我仍然只在方法中得到 null。
我错过了什么?
奇怪的是下面的工作正常。
@Html.ActionLink("Poof", "Record", "Home",
new Thing(),
new { @class = "nav-link" })
public ActionResult Record(Thing count) { ... }
很难根据您的问题中提供的信息说出您的代码可能有什么问题,但假设 全部默认值 (新创建的 ASP.NET MVC 应用程序 Visual Studio),如果您在 ~/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>
所以我想现在您应该问自己的问题是:我的设置与 Darin 在此处概述的设置有何不同?回答这个问题可能是解决问题的关键。
更新:
好的,现在你的问题好像变了。您似乎试图将复杂的对象传递给您的控制器操作:
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
}
您使用 @Html.ActionLink()
的 overload,期望第 4 个参数是 typeof object
。在内部,该方法通过使用对象中每个 属性 的 .ToString()
值构建一个 RouteValueDictionary
。
在您的情况下,您的 'object'(int
)没有属性,因此不会生成路由值,url 将只是 /Home/Action
(而您程序崩溃,因为您的方法需要一个非空参数)。
例如,如果您将其更改为
@Html.ActionLink("Poof", "Action", "Home", "10", new { @class = "nav-link" })
即引用第四个参数,url 现在将是 /Home/Action?length=2
因为 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]
(并且绑定会失败)所以要小心传递复杂对象在行动中 link
首先,我认为我再次使用了错误的重载(API 中一个非常常见的问题 - 每个人都被那个问题绊倒了)。但是你不知道吗?不是这个。我实际上也有 HTML attributes 参数,我用 intellisense 验证这是我输入的路由值。
@Html.ActionLink("Poof", "Action", "Home", 10, new { @class = "nav-link" })
然而,似乎下面的接收方法只能看到 null 并崩溃,因为它无法从中生成整数。
public ActionResult Record(int count) { ... }
我尝试了一些方法:将参数类型更改为 int? 和 string(程序停止崩溃但值为仍然为空)。我已经测试过将传递的值打包为一个对象(with/without @)。
@Html.ActionLink("Poof", "Record", "Home",
new { count = "bamse" },
new { @class = "nav-link" })
我可以看到生成的锚点具有我作为查询字符串的值,所以更改就在那里。但是,我仍然只在方法中得到 null。
我错过了什么?
奇怪的是下面的工作正常。
@Html.ActionLink("Poof", "Record", "Home",
new Thing(),
new { @class = "nav-link" })
public ActionResult Record(Thing count) { ... }
很难根据您的问题中提供的信息说出您的代码可能有什么问题,但假设 全部默认值 (新创建的 ASP.NET MVC 应用程序 Visual Studio),如果您在 ~/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>
所以我想现在您应该问自己的问题是:我的设置与 Darin 在此处概述的设置有何不同?回答这个问题可能是解决问题的关键。
更新:
好的,现在你的问题好像变了。您似乎试图将复杂的对象传递给您的控制器操作:
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
}
您使用 @Html.ActionLink()
的 overload,期望第 4 个参数是 typeof object
。在内部,该方法通过使用对象中每个 属性 的 .ToString()
值构建一个 RouteValueDictionary
。
在您的情况下,您的 'object'(int
)没有属性,因此不会生成路由值,url 将只是 /Home/Action
(而您程序崩溃,因为您的方法需要一个非空参数)。
例如,如果您将其更改为
@Html.ActionLink("Poof", "Action", "Home", "10", new { @class = "nav-link" })
即引用第四个参数,url 现在将是 /Home/Action?length=2
因为 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]
(并且绑定会失败)所以要小心传递复杂对象在行动中 link