Asp.net mvc 具有默认值的可空枚举帮助器

Asp.net mvc 具有默认值的可空枚举帮助器,asp.net-mvc,nullable,html.dropdownlistfor,Asp.net Mvc,Nullable,Html.dropdownlistfor,我最近做了一个扩展,用于将dropdownlist绑定到模型, 不幸的是,我无法将-want-be-default-“please select…”选为默认值 下拉列表的索引始终为1,并选择枚举的第一项作为默认项。 我根据达林的回答做了扩展- 有人建议我使用可空枚举, 我还不能让它工作,希望能得到帮助 辅助对象中默认选择文本的指定: return htmlHelper.DropDownListFor(expression, items, "Please select ..."); 如何在任何下

我最近做了一个扩展,用于将dropdownlist绑定到模型, 不幸的是,我无法将-want-be-default-“please select…”选为默认值 下拉列表的索引始终为1,并选择枚举的第一项作为默认项。 我根据达林的回答做了扩展-

有人建议我使用可空枚举, 我还不能让它工作,希望能得到帮助

辅助对象中默认选择文本的指定:

return htmlHelper.DropDownListFor(expression, items, "Please select ...");
如何在任何下拉列表中将“请选择…”选为默认值

在我使用的ViewModel中:

public TimePlan? TimeList { get; set; }

你做错了。应该为空的不是时间列表,而是应该存储选定项的时间计划属性。以下是视图模型中应该包含的内容:

public TimePlan? TheTimePlan { get; set; }

public IEnumerable<SelectListItem> TimeList
{
    get
    {
        var enumType = typeof(TimePlan);
        var values = Enum.GetValues(enumType).Cast<TimePlan>();

        return
            from value in values
            select new SelectListItem
            {
                Text = Enum.GetName(typeof(TimePlan), value),
                Value = value.ToString(),
            };
    }
}
更新:

如果要创建自定义html帮助器,可以按如下方式执行:

public static IHtmlString DropDownListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TEnum>> expression, string optionLabel)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    var enumType = GetNonNullableModelType(metadata);
    var values = Enum.GetValues(enumType).Cast<TEnum>();            

    var items =
        from value in values
        select new SelectListItem
        {
            Text = Enum.GetName(enumType, value),
            Value = value.ToString(),
            Selected = value.Equals(metadata.Model)
        };

    return htmlHelper.DropDownListFor(expression, items, optionLabel);
}

private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
    Type modelType = modelMetadata.ModelType;

    Type underlyingType = Nullable.GetUnderlyingType(modelType);
    if (underlyingType != null)
    {
        modelType = underlyingType;
    }
    return modelType;
}

我知道删除第二部分是为了不引起对以下问题的误解:html中呈现的是什么?你检查过了吗?无法准确理解你的意思,枚举已完全呈现,我在顶部有选择提示,问题是它未被选中,索引1将是选中的项。我使用类似“@Html.DropDownListForEnum(x=>x.TheTimePlan)”的东西,正如我在那里评论的那样,我尝试了这一点,但效果并不理想:“我尝试过这样的测试:返回htmlHelper.DropDownListFor(表达式,项,“请从下面的列表中选择”);但是dropdownlist的所选索引始终为“1”而不是“0”。。我正在使用代码来找到解决方法,并让您知道,感谢您在您的代码和之前的帖子之间没有发现任何差异。只有两个小差异。1-时间计划在我的代码中可以为空(
时间计划?
).2-DropDownList for html帮助程序有一个optionLabel参数(“请选择…”)。而且,它是有效的。我已经对它进行了测试。这是基于为另一个问题提供的答案中的第一个解决方案。你不必为类似的问题创建自定义html帮助程序。如果你想使用自定义html帮助程序,请查看我的更新答案。我不在这里,但朋友,你知道我不是在寻找一个大的答案,确切的答案正如我之前看到和尝试过的,你提到的所有东西都在我提到的链接中,我认为你没有亲自测试它,因为结果是相同的,并且没有在页面加载上显示OptionLabel(它隐藏在组合框下面)。
public static IHtmlString DropDownListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TEnum>> expression, string optionLabel)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    var enumType = GetNonNullableModelType(metadata);
    var values = Enum.GetValues(enumType).Cast<TEnum>();            

    var items =
        from value in values
        select new SelectListItem
        {
            Text = Enum.GetName(enumType, value),
            Value = value.ToString(),
            Selected = value.Equals(metadata.Model)
        };

    return htmlHelper.DropDownListFor(expression, items, optionLabel);
}

private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
    Type modelType = modelMetadata.ModelType;

    Type underlyingType = Nullable.GetUnderlyingType(modelType);
    if (underlyingType != null)
    {
        modelType = underlyingType;
    }
    return modelType;
}
@Html.DropDownListForEnum(model => model.TheTimePlan, "Please select...")