绑定到数据库时,下拉列表中的值默认为列表顶部的值

Value from Drop Down List defaults to value at the top of the list when binding to database

我正在构建一个用于数据输入的表单,但是用户必须填写的下拉列表之一是一个下拉列表,该列表是从已更改为用户友好格式的枚举中填充的。下拉列表的默认选项为 'please select...'。但是,无论用户选择什么,单击提交按钮并将条目保存在数据库中时,保存的条目始终是第一个枚举,即列表顶部的值,我不明白为什么。

这是模型:

public enum Medium
{
    [Description("Teleconference & Report")]
    Teleconference_Report,
    [Description("Email & Telephone")]
    Email_Telephone
}

[Required]
[Display(Name = "Medium")]
public Medium Medium { get; set; }

这是表单中的字段:

<div class="form-group">
    @Html.LabelFor(model => model.Medium, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-5">
        @Html.DropDownList("MediumID", null, "Please select...", htmlAttributes: new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.Medium, "", new { @class = "text-danger" })
    </div>
</div>

"MediumID" DropDownList 是使用一个 viewbag 填充的,该 viewbag 设置为以下 returns:

// Puts all of the mediums of communication into a user friendly dropdownlist.
public List<SelectListItem> GetMediumList()
{
    List<SelectListItem> mediumList = new List<SelectListItem>();

    foreach (Medium state in EnumToList<Medium>())
    {
        mediumList.Add(new SelectListItem
        {
            Text = GetEnumDescription(state),
            Value = state.ToString(),
        });
    }

    return mediumList;
}

下面显示了另一个名为 'Frequency' 的枚举的表单部分,但这些未更改为用户友好的字符串,因此使用原始的 EnumDropDownListFor 帮助程序。

<div class="form-group">
    @Html.LabelFor(model => model.Frequency, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-5">
        @Html.EnumDropDownListFor(model => model.Frequency, "Please select...", htmlAttributes: new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.Frequency, "", new { @class = "text-danger" })
    </div>
</div>

下面显示了将枚举转换为用户友好字符串的两种方法:

// Returns a 'user friendly', readable version of the enum.
public static string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes =
        (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

    if (attributes != null && attributes.Length > 0)
        return attributes[0].Description;
    else
        return value.ToString();
}

// Puts all of the same enums into a list.
public static IEnumerable<T> EnumToList<T>()
{
    Type enumType = typeof(T);

    // Can't use generic type constraints on value types,
    // so have to do check like this.
    if (enumType.BaseType != typeof(Enum))
        throw new ArgumentException("T must be of type System.Enum");

    Array enumValArray = Enum.GetValues(enumType);
    List<T> enumValList = new List<T>(enumValArray.Length);

    foreach (int val in enumValArray)
    {
        enumValList.Add((T)Enum.Parse(enumType, val.ToString()));
    }

    return enumValList;
}

最后,这里是方法签名 binded/bound:

public ActionResult Create([Bind(Include = "Point,ApplicationID,MediumID,Frequency,StartDate,EndDate")] TouchPoint touchPoint)

非常感谢任何帮助。

假设您使用 GetEnumDescription 方法填充 ViewBag.MediumList,您需要绑定 Medium 属性 而不是 MediumID 并使用 ViewBag.MediumList 作为下拉列表的数据源:

<div class="form-group">
    @Html.LabelFor(model => model.Medium, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-5">
        @Html.DropDownListFor(model => model.Medium, (List<SelectListItem>)ViewBag.MediumList, "Please select...", htmlAttributes: new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.Medium, "", new { @class = "text-danger" })
    </div>

控制台:

public ActionResult Create([Bind(Include = "Point,ApplicationID,Medium,Frequency,StartDate,EndDate")] TouchPoint touchPoint)

如果你还需要 MediumId 属性 - 我想你可以计算一下 属性:

public int MediumId{
   get{
      return (int)this.Medium;
   }
}

However, no matter what the user selected, when the submit button is clicked and the entry is saved in the database, the saved entry is always the first enum i.e. the value at the top of the list and I can't figure out why

原因是枚举基本上是一个 int,它的默认值为 0。当您以这种方式定义枚举时:

public enum Medium
{
    [Description("Teleconference & Report")]
    Teleconference_Report,
    [Description("Email & Telephone")]
    Email_Telephone
}

Teleconference_Report 值为 0,Email_Telephone 值为 1,这使得 Teleconference_Report 成为此枚举的默认值。由于您的 Medium 属性 未正确绑定,因此它始终设置为默认 Teleconference_Report 值。