通过 ViewData 使用 DropDownList 的 SelectList 的强类型视图:提交时类型不匹配
我正在尝试在 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>
其结果的 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)
{
...
(我尝试添加 [Bind (Exclude="eventTypeId ")]
位于“CalendarEvent newEvent”参数前面,但它不会改变行为。)
问题:当我提交表单时,出现 InvalidOperationException 异常:
具有键的 ViewData 项 “eventTypeId”的类型 'System.Int32' 但必须是类型 'IEnumerable
'。
我在这里和 MVC 博客上查看了许多示例,但到目前为止还不清楚它应该如何工作(看起来基于许多示例,它应该按原样工作)。我是否需要创建第二个模型,该模型具有 SelectListItem 类型的变量来接受 SelectListItem 并将值转换为 System.Int32 以实际设置 eventTypeId?这看起来相当绕。
I am trying to create a form in ASP.NET MVC2 RC 2 that is based on a calendar event object. The object has eventTypeId which is a System.Int32 that I need to populate with via a select list.
The controller to create the initial view is:
[WAuthorize]
public ActionResult AddCalendarEvent()
{
CalendarEventTypesManager calendarEventTypesManager =
new CalendarEventTypesManager();
ViewData["eventTypeId"] = new SelectList(
calendarEventTypesManager.SelectAll(), "Id", "Type");
return View();
}
The snippet of the View (with the header) is:
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Extranet.master"
Inherits="System.Web.Mvc.ViewPage<SomeProject.Models.CalendarEvent>" %>
...
<p><%= Html.DropDownList("eventTypeId") %></p>
Which results the HTML of:
<p>
<select id="eventTypeId" name="eventTypeId">
<option value="1">All school activities</option>
<option value="2">All school event</option>
</select>
</p>
The POST-accepting controller is:
[WAuthorize]
// TODO research some more
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult AddCalendarEvent(CalendarEvent newEvent)
{
...
(I've tried adding [Bind (Exclude="eventTypeId")]
in front of the "CalendarEvent newEvent" parameter but it does not change the behavior.)
Problem: When I submit the form, I get an InvalidOperationException exception:
The ViewData item that has the key
'eventTypeId' is of type
'System.Int32' but must be of type
'IEnumerable<SelectListItem>'.
I've looked at a number of examples here and on the MVC blogs but so far it isn't clear how this is supposed to work (it looks like based on many examples, it should work as is). Do I need to create a second model that has a variable of type SelectListItem to accept the SelectListItem and convert the value to a System.Int32 to actually set eventTypeId? That seems rather round about.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
经过更多思考后,我认为也许我需要在接收发布值的控制器操作中填充 ViewData["eventTypeID"] ——而不仅仅是在设置表单的控制器操作中。我尝试过并且成功了。
接受 POST 的控制器操作已更改(添加此列表中的最后两行):
我不清楚,因此希望其他人也发现这很有用。我使用 Firefox 的 LiveHTTPHeaders 插件检查了实际的 HTTP POST,确实,entryTypeID 被发布为“...&entryTypeId=2&...”(我在提交之前选择了表单上的第二项),但是我们是否重新加载选择发布到控制器中的列表进行验证?
After thinking about this some more, I thought that maybe I needed to populate
ViewData["eventTypeID"]
in the controller action that receives the posted values -- not just in the controller action that sets up the form. I tried that and it worked.The controller action that accepts the POST was altered (adding the last two lines in this listing):
That was not clear to me so hopefully someone else finds this useful too. I checked the actual HTTP POST with LiveHTTPHeaders plugin for Firefox and indeed entryTypeID is posted as "...&entryTypeId=2&..." (I had selected the second item on the form before submitting) but do we reload the select list in the posted-to controller to do validation?
如果 ViewData 不包含视图上所有字段所需的值并且 ViewData 被发回视图,则会出现此问题。
This problem occurs if the ViewData does not contain required values for all the fields on the view and the ViewData is posted back to the view.