编辑: 我不确定我以前是怎么错过的,但这可能是Binding a dictionary contains a list in MVC4 的副本。
我正在使用 ASP.NET MVC4,并且我有一个字典属性,该属性以枚举为键,并有一个类作为其值类型。我正在使用Html.TextBoxFor
为将其中之一作为视图模型的控制器操作生成表单的 HTML。InvalidCastException
当我通过浏览器提交表单时,我在绑定期间得到了一个。
这是视图模型:
public class MyViewModel
{
public virtual IDictionary<MyEnumType, IList<MySubViewModel>> Subs { get; set; }
public class MySubViewModel
{
public virtual String Name { get; set; }
}
}
在控制器中,我有:
[HttpGet]
public ActionResult EditPage(Int32? id)
{
MyViewModel testViewModel = new MyViewModel
{
Subs = new Dictionary<MyEnumType, IList<MyViewModel.MySubViewModel>>() {
{
MyEnumType.MySubViewModel
, new List<MyViewModel.MySubViewModel> {
new MyViewModel.MySubViewModel {
Name = "Foo-Bar"
}
}
}
}
};
return View(testViewModel);
}
[HttpPost]
public ActionResult EditPage(MyViewModel model)
{
return View(model);
}
我认为(使用 Spark 视图引擎):
<tbody each="var enumValue in Html.EnumValues<MyEnumType>()">
<tr each="var sub in Model.Subs[enumValue]" class="DataRow">
<td>
${Html.TextBoxFor(m => m.Subs[enumValue][subIndex].Name, new { @class="SubName" })}
</td>
</tr>
</tbody>
这被渲染为:
<tbody>
<tr>
<td>
<input id="Subs_EnumValueOne__0__Name" type="text" value="Foo-Bar" name="Subs[EnumValueOne][0].Name">
</td>
</tr>
</tbody>
当我提交页面时,我得到一个InvalidCastException
: {"Specified cast is not valid."}
。
at System.Web.Mvc.DefaultModelBinder.CollectionHelpers.ReplaceDictionaryImpl[TKey,TValue](IDictionary`2 dictionary, IEnumerable`1 newContents)
这是堆栈跟踪。(我有一个不同类型的模型绑定器,但是对于这个字典属性,它只是传递给base.BindModel
.)
[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
System.Web.Mvc.DefaultModelBinder.UpdateDictionary(ControllerContext controllerContext, ModelBindingContext bindingContext, Type keyType, Type valueType) +1211
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +921
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +416
Namespace.For.MyBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1195
System.Web.Mvc.DefaultModelBinder.GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) +17
System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +384
System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +88
System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +53
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1314
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +416
Namespace.For.MyBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1195
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +317
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +117
System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) +446
System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +302
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +30
System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +382
System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +317
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +15
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +71
System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +249
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155