为可以为空的枚举创建单选按钮列表

时间:2015-08-04 18:43:48

标签: c# asp.net-mvc enums

我有以下代码将Enum成功转换为radiobutton列表。但是,如果Enum可以为空,则它不起作用。是否可以允许可以为空的枚举?

public static MvcHtmlString EnumRadioButtonListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        var listOfValues = Enum.GetNames(metaData.ModelType);  //<--- It errors here if the enum is nullable

        var sb = new StringBuilder();

        if (listOfValues != null)
        {             
            sb = sb.AppendFormat(@"<span class=""radio"">");

            // Create a radio button for each item in the list
            foreach (var name in listOfValues)
            {
                var label = name;

                var memInfo = metaData.ModelType.GetMember(name);

                if (memInfo != null)
                {
                    var attributes = memInfo[0].GetCustomAttributes(typeof(DisplayAttribute), false);

                    if (attributes != null && attributes.Length > 0)
                        label = ((DisplayAttribute)attributes[0]).Name;
                }

                var id = string.Format(
                    "{0}_{1}_{2}",
                    htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix,
                    metaData.PropertyName,
                    name
                );

                int enumValue = (int)Enum.Parse(metaData.ModelType, name);

                var radio = htmlHelper.RadioButtonFor(expression, enumValue, new { id = id }).ToHtmlString();

                sb.AppendFormat(@"<label for=""{0}"">{1}{2}</label><br />", id, radio, label);
            }

            sb = sb.AppendFormat("</span>");
        }

        return MvcHtmlString.Create(sb.ToString());
    }

我在代码中注明的错误是:

  

提供的类型必须是枚举。参数名称:enumType

这就是我使用MVC实现它的方式:

类别:

    public enum IdTypes
    {
        [Display(Name="Driver's License")]
        DriversLicense = 1,
        [Display(Name="State ID")]
        StateID = 2,
        [Display(Name="US Passport")]
        UsPassport = 3,
        [Display(Name="Green Card")]
        GreenCard = 4
    }

    [Display(Name="Photo ID Provided")]
    [UIHint("EnumRadioButtonListFor")]
    public IdTypes? PhotoIDProvidedSecondary { get; set; }

剃刀:

    <div class="form-group">
        @Html.LabelFor(model => model.PhotoIDProvidedSecondary, htmlAttributes: new { @class = "control-label col-md-3" })
        <div class="col-md-2">
            @Html.EditorFor(model => model.PhotoIDProvidedSecondary, new { htmlAttributes = new { @class = "form-control" } })
        </div>
        <div class="col-md-4">
            <p class="form-control-static">@Html.ValidationMessageFor(model => model.PhotoIDProvidedSecondary, "", new { @class = "text-danger" })</p>
        </div>
    </div>

EditorTemplate(EnumRadioButtonListFor):

@model Enum
@using BrokerDealer.Extensions

@if (EnumHelper.IsValidForEnumHelper(ViewData.ModelMetadata))
{
    @Html.EnumRadioButtonListFor(model => model)
}
else
{
    @Html.TextBoxFor(model => model, htmlAttributes: new { @class = "form-control" })
}

1 个答案:

答案 0 :(得分:2)

我目前无法对其进行测试,但如果您更改了该行未能:

var myEnum = Nullable.GetUnderlyingType(metaData.ModelType) ?? metaData.ModelType;
var listOfValues = Enum.GetNames(myEnum);

你应该得到你期望的结果。