代码之家  ›  专栏  ›  技术社区  ›  Cymen

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

  •  5
  • Cymen  · 技术社区  · 14 年前

    我正在尝试在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();
    }
    

    视图的片段(带标题)是:

    <%@ Page Title="" Language="C#" 
        MasterPageFile="~/Views/Shared/Site.Extranet.master"
        Inherits="System.Web.Mvc.ViewPage<SomeProject.Models.CalendarEvent>" %>
    
    ...
    
    <p><%= Html.DropDownList("eventTypeId") %></p>
    

    其结果是:

    <p>
    <select id="eventTypeId" name="eventTypeId">
        <option value="1">All school activities</option> 
        <option value="2">All school event</option> 
    </select>
    </p> 
    

    接收后控制器为:

    [WAuthorize]
    // TODO research some more
    [ValidateInput(false)]              
    [AcceptVerbs(HttpVerbs.Post)]
    [ValidateAntiForgeryToken]
    public ActionResult AddCalendarEvent(CalendarEvent newEvent)
    {
        ...
    

    (我试着增加 [Bind (Exclude="eventTypeId")] 在“CalendarEvent NewEvent”参数前面,但不会更改行为。)

    问题:提交表单时,我得到一个InvalidOperationException异常:

    具有键的ViewData项 “EventTypeID”的类型为 “System.Int32”,但必须是类型 'IEnumerable<SelectListItem>'。

    我在这里和MVC博客上看过很多例子,但是到目前为止还不清楚这是如何工作的(基于很多例子,它应该是正常工作的)。是否需要创建第二个具有selectListItem类型变量的模型来接受selectListItem并将该值转换为System.Int32以实际设置EventTypeID?这似乎相当圆滑。

    2 回复  |  直到 11 年前
        1
  •  7
  •   Cymen    14 年前

    再考虑一下,我想也许我需要 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");
            ....
    

    我不清楚,所以希望其他人也能发现这一点。我用火狐的livehttpheaders插件检查了实际的HTTP日志,实际上entrytypeid被发布为“…&entrytypeid=2&…”(提交前我在表单上选择了第二个项目),但是我们是否在“发布到控制器”中重新加载选择列表以进行验证?

        2
  •  2
  •   Ashraf    14 年前

    如果视图数据不包含视图上所有字段所需的值,并且视图数据被发布回视图,则会出现此问题。