我有一个网页,其中包含一个由枚举填充的下拉列表。
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个值。如果我选择“区域类型”“国家/地区”或“城市/城镇”,则模型的“RegionType”属性无法将其转换为MVC控制器POST操作中的相应枚举。如何让它正确地进行翻译?
答案 0 :(得分:1)
您可以定义以下扩展方法,将枚举类型转换为可由DropDownListFor
帮助程序使用的SelectList:
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>
}
答案 1 :(得分: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);
}