2

我有一个由枚举填充的下拉列表的网页。

public enum RegionType
{
    State,
    [System.Xml.Serialization.XmlEnumAttribute("County/District")]
    County_District,
    [System.Xml.Serialization.XmlEnumAttribute("City/Town")]
    City_Town,
    Municipality,
    Village
}

下拉列表实际上通过以下方法表示枚举:

public static List<string> GetRegionTypes()
{
    List<string> theReturn = new List<string>();
    theReturn.Add("");
    foreach (RegionType s in Enum.GetValues(typeof(RegionType))) {
        theReturn.Add(GetXmlEnumValue(s));
    }
    return theReturn;
}

效果很好,下拉菜单显示正确的值和所有内容。问题在于我具有“xmlenum”属性的 2 个值。如果我选择区域类型“国家/地区”或“城市/城镇”,则模型的“区域类型”属性无法将其转换为 MVC 控制器 POST 操作中的相应枚举。我如何让它正确地进行翻译?

4

2 回答 2

1

您可以定义以下扩展方法,将枚举类型转换为帮助程序可以使用的 SelectList DropDownListFor

public static class EnumExtensions
{
    public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
    {
        var enumType = typeof(TEnum);
        if (enumType.IsGenericType && enumType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            enumType = enumType.GetGenericArguments()[0];
        }

        var fields = enumType.GetFields(
            BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public
        );
        var values = Enum.GetValues(enumType).OfType<TEnum>();
        var items =
            from value in values
            from field in fields
            let xmlEnumAttribute = field
                .GetCustomAttributes(
                    typeof(XmlEnumAttribute), true
                )
                .OfType<XmlEnumAttribute>()
                .FirstOrDefault()
            let name = (xmlEnumAttribute != null)
                ? xmlEnumAttribute.Name
                : value.ToString()
            where value.ToString() == field.Name
            select new { Id = value, Name = name };
        return new SelectList(items, "Id", "Name", enumObj);
    }
}

然后很容易。你有一个视图模型:

public class MyViewModel
{
    [Required]
    public RegionType? Region { get; set; }
}

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Region = RegionType.City_Town
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }
        return Content("Thanks for choosing " + model.Region.Value.ToString());
    }
}

和一个观点:

@model MyViewModel

@using (Html.BeginForm())
{
    @Html.DropDownListFor(x => x.Region, Model.Region.ToSelectList(), "-- Region --")
    @Html.ValidationMessageFor(x => x.Region)
    <button type="submit">OK</button>
}
于 2012-09-22T08:19:04.800 回答
0

如果它仅用于显示目的,我们使用 Description 属性,(使用 System.ComponentModel):

public enum SelectedAddressType
{
    [Description("Primary Site")]
    PrimarySite = 1, 

    [Description("Registered Office")]
    RegisteredOffice = 2, 

    [Description("Alternative Invoice Address")]
    Alternative = 3
}

显示它:

@Html.EnumDropDownListFor(model => model.SelectedInvoiceAddress, new { id = "selInvAdd" }, "Select")

有了这个助手:

    public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes, string selectItem)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        Type enumType = GetNonNullableModelType(metadata);
        IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();

        IEnumerable<SelectListItem> items = from value in values
                                            select new SelectListItem
                                            {
                                                Text = GetEnumDescription(value),
                                                Value = value.ToString(),
                                                Selected = value.Equals(metadata.Model)
                                            };

        // If the enum is nullable, add an 'empty' item to the collection
        if (metadata.IsNullableValueType)
            items = SingleEmptyItem.Concat(items);

        if(!string.IsNullOrEmpty(selectItem))
            return htmlHelper.DropDownListFor(expression, items, selectItem, htmlAttributes);

        return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
    }
于 2012-09-22T08:25:45.080 回答