为什么当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>

为什么当url参数与模型中的字段相同时,EnumDropDownListFor没有绑定正确

这是默认行为。您的参数命名为eventType,因此当调用该方法时,DefaultModelBindereventType的值添加到ModelState(将是null)。

当您使用html helper时,在您的例子中是EnumDropDownListFor(),它们使用ModelState的值(如果存在的话)而不是您的属性的实际值,因此helper有效地使用null的值,而不是Type2的值进行绑定。因为null不匹配任何一个枚举值,所以选择第一个值(Type1)(因为有些值必须匹配)。

此行为的原因将在本回答的第二部分中解释。

最简单的解决方案是更改参数的名称,使其与您的属性之一的名称不匹配(注意DefaultModelBinder不区分大小写,因此eventTypeEventType实际上是相同的)。另一个方法是在初始化TestMode对象之前添加ModelState.Clear()

相关文章:
  • 没有找到相关文章