无法在 MVC 5 中为 Html.DropDownList 设置默认值

Unable to set default value for Html.DropDownList in MVC 5

我在 Edit view 中将枚举显示为下拉列表,如下所示:

内部模型

public enum PaymentType
{
    Self=1,
    Insurer=2,
    PrivateCompany=3

}
public PaymentType PaymentTypeSelected { get; set; }

内部控制器

ViewBag.EnumList = Patient.PaymentType.Insurer.ToSelectList();
patient.PaymentTypeSelected=Patient.PaymentType.Insurer;

在视图中

@Html.DropDownListFor(m => m.PaymentTypeSelected, 
    ViewBag.EnumList as SelectList)

还有一个扩展函数

public static System.Web.Mvc.SelectList ToSelectList<TEnum>(this TEnum obj)
        where TEnum : struct, IComparable, IFormattable, IConvertible
{
    return new SelectList(Enum.GetValues(typeof(TEnum)).OfType<Enum>()
        .Select(x => new SelectListItem
        {
           Text = Enum.GetName(typeof(TEnum), x),
           Value = (Convert.ToInt32(x)).ToString()
        }), "Value", "Text");
    }

生成HTML

<select data-val="true" 
        data-val-required="The PaymentTypeSelected field is required."
        id="ptype" name="PaymentTypeSelected">
    <option value="1">Self</option>
    <option value="2">Insurer</option>
    <option value="3">PrivateCompany</option>
</select>

我觉得一切正常,但下拉列表不显示默认选择值(在我的例子中 Insurer)。谁能指出我在这里做错了什么?

试试这个...

 @Html.DropDownListFor(m => ((int)m.PaymentTypeSelected).ToString(), ViewBag.EnumList as SelectList)

正如 Stephen 所指出的,如果您使用 DropDownListFor,这将不起作用,因为模型绑定更喜欢 m=>m.SomeProperty 而不是构造函数参数。

您可以使用带有第 4 个对象参数的 SelectList 构造函数来指示所选值: https://msdn.microsoft.com/en-us/library/dd492553(v=vs.118).aspx

// in controller we'll pass the desired selected value to extension method:
ViewBag.EnumList = Patient.PaymentType.Insurer.ToSelectList(Patient.PaymentType.Insurer);

// update method to support this parameter
public static System.Web.Mvc.SelectList ToSelectList<TEnum>(this TEnum obj, object selectedValue)
        where TEnum : struct, IComparable, IFormattable, IConvertible // correct one
    {
        return new SelectList(
            Enum.GetValues(typeof(TEnum)).OfType<Enum>()
                 .Select(x =>
                     new SelectListItem
                     {
                         Text = Enum.GetName(typeof(TEnum), x),
                         Value = (Convert.ToInt32(x)).ToString()
                     }
                 ) 
            ,"Value", "Text"
            ,(int)selectedValue); // pass selected value to SelectList constructor

    }

我进行了一次编辑以添加 (int),由于我们来自 object,所以这有点脏。这当然可以改进。

这里是as a working DotNetFiddle

简而言之,您需要确保每个 SelectListItemValue 属性 和 PaymentTypeSelected 属性 都来自同一个枚举转换。您正在为 Valueint,为 PaymentTypeSelectedstring。把你的分机改成这个,你就成功了。

public static class MyExtensions
{
    public static SelectList ToSelectList<TEnum>(this TEnum obj) 
        where TEnum : struct, IComparable, IFormattable, IConvertible
    {
        var items = Enum.GetValues(typeof (TEnum))
                .OfType<Enum>()
                .Select(x => new { Text = x.ToString() })
                .Select(x => new SelectListItem
                {
                    Text = x.Text, 
                    Value = x.Text
                });

        return new SelectList(items, "Value", "Text");
    }
}

A SelectList 可以接受 4 个参数,其中最后一个参数 selectedValue 是列表中任何类型的对象。所以你可以像下面这样尝试:

ViewBag.yourEnumList= new SelectList(enumList, "Value", "Text", selectedValue);

或者,您可以在扩展函数中应用它