我正在尝试在ASP.NET MVC2 RC 2中创建一个基于日历事件对象的表单。该对象有eventTypeId,它是我需要通过选择列表填充的System.Int32。
创建初始视图的控制器是:
[WAuthorize]
public ActionResult AddCalendarEvent()
{
CalendarEventTypesManager calendarEventTypesManager =
new CalendarEventTypesManager();
ViewData["eventTypeId"] = new SelectList(
calendarEventTypesManager.SelectAll(), "Id", "Type");
return View();
}
View的片段(带标题)是:
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Extranet.master"
Inherits="System.Web.Mvc.ViewPage<SomeProject.Models.CalendarEvent>" %>
...
<p><%= Html.DropDownList("eventTypeId") %></p>
结果是HTML:
<p>
<select id="eventTypeId" name="eventTypeId">
<option value="1">All school activities</option>
<option value="2">All school event</option>
</select>
</p>
接受POST的控制器是:
[WAuthorize]
// TODO research some more
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult AddCalendarEvent(CalendarEvent newEvent)
{
...
(我尝试在“CalendarEvent newEvent”参数前面添加[Bind (Exclude="eventTypeId")]
,但它不会改变行为。)
问题:当我提交表单时,我收到一个InvalidOperationException异常:
具有键的ViewData项 'eventTypeId'属于类型 'System.Int32'但必须是类型 '的IEnumerable&LT; SelectListItem&GT;'。
我在这里和MVC博客上看了很多例子,但到目前为止还不清楚它应该如何工作(看起来基于很多例子,它应该按原样运行)。我是否需要创建第二个具有SelectListItem类型变量的模型来接受SelectListItem并将值转换为System.Int32以实际设置eventTypeId?这似乎相当圆润。
答案 0 :(得分:7)
在考虑了这个之后,我想也许我需要在接收发布值的控制器动作中填充ViewData["eventTypeID"]
- 而不仅仅是在设置表单的控制器动作中。我试过了,但确实有效。
接受POST的控制器操作已被更改(添加此列表中的最后两行):
[WAuthorize]
[ValidateInput(false)] // TODO research some more
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult AddCalendarEvent(CalendarEvent newEvent)
{
CalendarEventTypesManager calendarEventTypesManager = new CalendarEventTypesManager();
ViewData["eventTypeId"] = new SelectList(calendarEventTypesManager.SelectAll(), "Id", "Type");
....
我不清楚,所以希望其他人也认为这也很有用。我用Firefox的LiveHTTPHeaders插件检查了实际的HTTP POST,并确实将entryTypeID发布为“...&amp; entryTypeId = 2&amp; ...”(我在提交前选择了表单上的第二项)但我们是否重新加载了选择发布到控制器中的列表进行验证?
答案 1 :(得分:2)
如果ViewData不包含视图上所有字段的必需值并且ViewData已发布回视图,则会出现此问题。