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

本文关键字:Html DropDownList 默认值 设置 MVC | 更新日期: 2024-09-27 09:32:22

我在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)。有人能指出我在这里做错了什么吗?

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

这里是一个工作的DotNetFiddle。

简而言之,您需要确保每个SelectListItemValue属性和PaymentTypeSelected属性都来自同一个Enum转换。您为Value执行int,为PaymentTypeSelected执行string。把你的分机号改成这个,你就是金子。

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");
    }
}

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

您可以使用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。这当然是可以改进的。

试试这个。。。

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

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

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

或者,您可以将其应用于扩展函数