通过ViewData为DropDownList提供SelectList的强类型视图:提交时类型不匹配

时间:2010-03-02 18:55:15

标签: asp.net-mvc post drop-down-menu selectlist selectlistitem

我正在尝试在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?这似乎相当圆润。

2 个答案:

答案 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已发布回视图,则会出现此问题。