【发布时间】:2013-05-31 12:25:34
【问题描述】:
我正在使用 MVC 4、.Net 4 和 Visual Studio 2012。
我正在尝试将一个相当复杂的模型用于我的一个视图,但在正确绑定它时遇到了严重的问题。
模型包装了一个字典,其中包含整数键和值,它们是布尔列表的列表。
基本上,对整数表示的项目进行了搜索,每个项目都有几个搜索词,对于每个词,我们都有一个结果列表。我在页面上显示结果,每个结果旁边都有一个复选框。对于每个结果,用户将通过选中该框来指示他们是否希望下一个操作完成某些事情。
目前,复选框正常显示,包括来自控制器的预设值,但是当我按下表单底部的提交按钮时,出现此错误:
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; }
}
以下是视图中的一些相关部分,更改了变量名以保护无辜者:
@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>
}
【问题讨论】:
-
在查看了上面包含的链接以及hanselman.com/blog/… 之后,我做了一些更改: 在循环之前:int kvInd = 0;更改: 为:
-
And:
<td>@Html.CheckBoxFor(m => m.SelectedResults[kv.Key][isr][i])</td>To:<td> <input type="checkbox" name="@("SelectedResults[ " + kvInd + " ].Value[ " + isr + " ][ " + i + " ]")" value="@Model.SelectedResults[kv.Key][isr][i]" /> <input type="hidden" name="@("SelectedResults[ " + kvInd + " ].Value[ " + isr + " ][ " + i + " ]")" value="false" /> </td>但我仍然遇到同样的错误。该死。
标签: asp.net-mvc razor dictionary checkbox viewmodel