为什么当url参数与模型中的字段相同时,EnumDropDownListFor没有绑定正确
本文关键字:EnumDropDownListFor 绑定 参数 url 模型 字段 为什么 | 更新日期: 2023-09-27 18:08:17
我有一个页面包含一个下拉列表,用于在模型中绑定字段的enum,我还有一个url参数具有相同的名称(第一个字母的大小写不相同)。
当url参数为空时,表示该enum的绑定不正确。为了澄清我的问题,请参阅下面的详细代码。
例如,url为Index?eventType=
时,视图最初显示的是Type1而不是Type2。MVC5有什么特殊的规则导致这种奇怪的行为吗?
当我改变url参数名或模型中的字段名时,加载Index?eventType=
时下拉列表可以选择Type2
视图:
@model TestMode
@{
Layout = null;
}
@Html.EnumDropDownListFor(m => m.EventType)
控制器:
public ActionResult Index(int? eventType)
{
var viewModel = new TestMode();
viewModel.EventType = eventType.HasValue ?
(CalendarEventType)eventType.Value :
CalendarEventType.Type2;
//Check the value of EventType here is CalendarEventType.Type2, but when the view loaded, there are not selected for the drop down list of enum
return View(viewModel);
}
ViewModel:
public class TestMode
{
public CalendarEventType EventType { get;set;}
}
public enum CalendarEventType
{
Type1 = 0,
Type2 = 1,
}
对于Index?eventType=
,没有选项可选。
<select data-val="true" data-val-required="EventType field is required" id="EventType" name="EventType">
<option value="0">Type1</option>
<option value="1">Type2</option>
</select>
这是默认行为。您的参数命名为eventType
,因此当调用该方法时,DefaultModelBinder
将eventType
的值添加到ModelState
(将是null
)。
当您使用html helper时,在您的例子中是EnumDropDownListFor()
,它们使用ModelState
的值(如果存在的话)而不是您的属性的实际值,因此helper有效地使用null
的值,而不是Type2
的值进行绑定。因为null
不匹配任何一个枚举值,所以选择第一个值(Type1
)(因为有些值必须匹配)。
此行为的原因将在本回答的第二部分中解释。
最简单的解决方案是更改参数的名称,使其与您的属性之一的名称不匹配(注意DefaultModelBinder
不区分大小写,因此eventType
和EventType
实际上是相同的)。另一个方法是在初始化TestMode
对象之前添加ModelState.Clear()
。