gpt4 book ai didi

asp.net-mvc - 使用复选框绑定(bind)到具有强类型 MVC View 的 bool 列表列表字典

转载 作者:行者123 更新时间:2023-12-03 18:49:37 26 4
gpt4 key购买 nike

我正在使用 MVC 4、.Net 4 和 Visual Studio 2012。

我正在尝试将一个相当复杂的模型与我的一个 View 一起使用,但我在让它正确绑定(bind)时遇到了严重的麻烦。

该模型包装了一个带有整数键的字典,以及作为 bool 列表列表的值。

基本上,对整数表示的项目进行了搜索,每个项目都有几个搜索词,对于每个词,我们都有一个结果列表。我在页面上显示结果,每个结果旁边都有一个复选框。对于每个结果,用户将通过选中该框来指示他们是否希望下一个操作完成某些事情。

目前,复选框正确显示,包括来自 Controller 的预设值,但是当我按下表单底部的提交按钮时,出现此错误:

Specified cast is not valid.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidCastException: Specified cast is not valid.

在我看来,这与使用字典有关,我被告知它不能很好地用作模型。我可能不得不换成别的东西,但我宁愿不要,除非我绝对必须这样做。似乎这里的某个地方可能有答案: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx , 或 Checkbox list for complex type in asp.net mvc , 或 How to bind Dictionary type parameter for both GET and POST action on ASP.NET MVC ,但是我在写完所有问题后找到了这些,但我还没有弄清楚,所以也许有人可以帮我一把。

这是堆栈跟踪的顶部:
[InvalidCastException: Specified cast is not valid.]
System.Web.Mvc.CollectionHelpers.ReplaceDictionaryImpl(IDictionary`2 dictionary, IEnumerable`1 newContents) +131

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +92
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +108
System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +19
System.Web.Mvc.CollectionHelpers.ReplaceDictionary(Type keyType, Type valueType, Object dictionary, Object newContents) +178

这是模型:
public class AutoResolveModel {
public Dictionary<int, List<List<bool>>> SelectedResults { get; set; }

public AutoResolveModel() {
SelectedResults = new Dictionary<int, List<List<bool>>>();
}
}

因为它可能是相关的,这里是 ViewBag.iidToData 的结构,它包含要显示的结果:
In the controller action:

var iidToData = new Dictionary<int, List<ItemSearchResult>>();
ViewBag.iidToData = iidToData;

Elsewhere:

public class ItemSearchResult {
public string C { get; set; }
public string S { get; set; }
public List<int> Ss { get; set; }
public List<int> Ks { get; set; }
}

以下是 View 中的一些相关部分,更改了变量名以保护无辜者:
@model AutoResolveModel

@{
string machineID;
Submission subm;
tblSignatures sig;
ItemSearchResult result;

var dc = new CloudDataContext();
}

@using( Html.BeginForm( "MyAction", "MyController", new { p = (int?) ViewBag.l }, FormMethod.Post ) ) {

foreach( KeyValuePair<int, List<ItemSearchResult>> kv in ViewBag.iidToData ) {

<input type="hidden" name="@("SelectedResults[ " + kv.Key + " ].Key")" value="@kv.Key" />

ID = (
...
).Single();

<h3>Inventory Item @ID</h3>

for(int isr = 0; isr < kv.Value.Count(); isr++) {

result = kv.Value[ isr ];

<h4>Searched for @result.S from @result.C</h4>

<table border="0">
<tr><th>K</th><th>I</th><th>V</th><th>G</th><th>D</th><th>S</th><th>T</th></tr>
@for( int i = 0; i < result.Ks.Count(); i++ ) {
subm = (
...
).FirstOrDefault();
try {
sig = (
...
).Single();
} catch {
sig = null;
}

if( subm != null && subm.K != 0 ) {

<tr>
<td>@Html.CheckBoxFor(m => m.SelectedResults[kv.Key][isr][i])</td>
<td>@result.Ks[ i ]</td>
<td>@subm.i</td>
<td>@subm.v</td>
<td>@subm.g</td>
<td>@subm.d</td>
@if( sig != null ) {
<td>@sig.S</td>
<td>@sig.T</td>
} else {
<td>N/A</td>
<td>N/A</td>
}
</tr>
}
}
</table>
}
}

<button type="submit">Search</button>
}

最佳答案

好吧,我明白了。

我尝试使用 Tuple >> 而不是 Dictionary >>。那失败了,显然是因为元组没有 0 参数构造函数。

然后,我尝试使用具有两个属性的自定义类,一个 int 和一个 List >。经过一番摆弄后,我得到了它的工作,一旦工作,我就能够对其进行逆向工程并让 Dictionary 工作。

这是工作版本(与以前相同的 View 模型和 iidToData):

...

@{
string machineID;
Submission subm;
tblSignatures sig;
ItemSearchResult result;

int kvInd = 0;

var dc = new CloudDataContext();
}

...

foreach( KeyValuePair<int, List<ItemSearchResult>> kv in ViewBag.iidToData ) {

...

<input type="hidden" name="@("Model.SelectedResults[" + kvInd + "].Key")" value="@kv.Key" />

for(int isr = 0; isr < kv.Value.Count(); isr++) {

...

@if(result.Keytbls.Any()) {

for( int i = 0; i < result.Keytbls.Count(); i++ ) {

...

<td>@Html.CheckBox( "Model.SelectedResults[" + kvInd + "].Value[" + isr + "][" + i + "]", Model.SelectedResults[ kv.Key ][ isr ][ i ] )</td>

...

} else {
<tr><td><input type="hidden" name="@("Model.SelectedResults[" + kvInd + "].Value[" + isr + "]")" /></td></tr>
}

...
}

kvInd++;

}

...

因此,用于字典键的隐藏输入的索引不是键,而是键值对的枚举,第 0 个、第 1 个、第 2 个,依此类推。这与稍后用于指示该值的索引相同。

这将我们引向另一个有趣的部分。复选框的名称需要包含 Model.DictionaryName[enumerationIndex].Value 以表明我们正在为该索引 KeyValue 对设置值。

此外,该辅助函数生成的 html 输入元素的值始终为 true,而第二个隐藏输入的值始终为 false。 “checked”属性表示输入复选框的值是否发送到默认活页夹,即它是否获得“true, false”或只是“false”的值。然后,绑定(bind)器将其正确解释为 bool 值。

最后,末尾 else block 中的隐藏输入为没有匹配搜索结果的条目添加了一个空的 List >。 .Value 与较早的 .Key 对指示要添加到字典中的完整 KeyValue 对。然后,当 binder 看到 Model.Dictionary[index].Value[index] 而没有看到 Model.Dictionary[index].Value[index][index] 时,它会创建一个空列表,但不会添加任何值。

所以这是不必要的复杂,但现在希望其他人可以在他们的 ViewModels 中使用带有 Collection 值的字典。

关于asp.net-mvc - 使用复选框绑定(bind)到具有强类型 MVC View 的 bool 列表列表字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16929162/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com