Intento actualizar mi proyecto a MVC3, algo que simplemente no puedo encontrar:
Tengo un tipo de datos simple de ENUMS:
public enum States()
{
AL,AK,AZ,...WY
}
Que quiero usar como DropDown / SelectList en mi vista de un modelo que contiene este tipo de datos:
public class FormModel()
{
public States State {get; set;}
}
Bastante sencillo: cuando uso la vista de generación automática para esta clase parcial, ignora este tipo.
Necesito una lista de selección simple que establezca el valor de la enumeración como el elemento seleccionado cuando presiono enviar y procesar a través de mi método AJAX - JSON POST.
Y que la vista (???!):
<div class="editor-field">
@Html.DropDownListFor(model => model.State, model => model.States)
</div>
¡Gracias de antemano por el consejo!
c#
asp.net-mvc-3
razor
jordan.baucke
fuente
fuente
Respuestas:
Acabo de hacer uno para mi propio proyecto. El siguiente código es parte de mi clase auxiliar, espero tener todos los métodos necesarios. Escribe un comentario si no funciona y lo comprobaré de nuevo.
public static class SelectExtensions { public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression) { if (expression.Body.NodeType == ExpressionType.Call) { MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body; string name = GetInputName(methodCallExpression); return name.Substring(expression.Parameters[0].Name.Length + 1); } return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1); } private static string GetInputName(MethodCallExpression expression) { // p => p.Foo.Bar().Baz.ToString() => p.Foo OR throw... MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression; if (methodCallExpression != null) { return GetInputName(methodCallExpression); } return expression.Object.ToString(); } public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class { string inputName = GetInputName(expression); var value = htmlHelper.ViewData.Model == null ? default(TProperty) : expression.Compile()(htmlHelper.ViewData.Model); return htmlHelper.DropDownList(inputName, ToSelectList(typeof(TProperty), value.ToString())); } public static SelectList ToSelectList(Type enumType, string selectedItem) { List<SelectListItem> items = new List<SelectListItem>(); foreach (var item in Enum.GetValues(enumType)) { FieldInfo fi = enumType.GetField(item.ToString()); var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault(); var title = attribute == null ? item.ToString() : ((DescriptionAttribute)attribute).Description; var listItem = new SelectListItem { Value = ((int)item).ToString(), Text = title, Selected = selectedItem == ((int)item).ToString() }; items.Add(listItem); } return new SelectList(items, "Value", "Text", selectedItem); } }
Úselo como:
Actualizar
He creado Html Helpers alternativos. Todo lo que necesita hacer para usarlos es cambiar su página de vista base en
views\web.config
.Con ellos puedes simplemente hacer:
Más información aquí: http://blog.gauffin.org/2011/10/first-draft-of-my-alternative-html-helpers/
fuente
using System.Web.Mvc.Html;
lo que necesite para acceder alSelectExtensionsClass
((int)item).ToString()
paraEnum.GetName(enumType, item)
obtener elSelectListItem
guardado correctamente como seleccionado, pero aún no funciona)Encontré una solución más simple para esto aquí: http://coding-in.net/asp-net-mvc-3-method-extension/
using System; using System.Linq.Expressions; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Html; namespace EnumHtmlHelper.Helper { public static class EnumDropDownList { public static HtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> modelExpression, string firstElement) { var typeOfProperty = modelExpression.ReturnType; if(!typeOfProperty.IsEnum) throw new ArgumentException(string.Format("Type {0} is not an enum", typeOfProperty)); var enumValues = new SelectList(Enum.GetValues(typeOfProperty)); return htmlHelper.DropDownListFor(modelExpression, enumValues, firstElement); } } }
Una línea de navaja lo hará:
@Html.DropDownListFor(model => model.State, new SelectList(Enum.GetValues(typeof(MyNamespace.Enums.States))))
También puede encontrar código para hacerlo con un método de extensión en el artículo vinculado.
fuente
@Html.DropDownListFor(model => model.State, new SelectList(Enum.GetValues(typeof(MyNamespace.Enums.States)),model.State))
A partir de ASP.NET MVC 5.1 (RC1) ,
EnumDropDownListFor
se incluye de forma predeterminada como método de extensión deHtmlHelper
.fuente
Si desea algo realmente simple, hay otra forma, dependiendo de cómo almacene el estado en la base de datos.
Si tuvieras una entidad como esta:
public class Address { //other address fields //this is what the state gets stored as in the db public byte StateCode { get; set; } //this maps our db field to an enum public States State { get { return (States)StateCode; } set { StateCode = (byte)value; } } }
Entonces generar el menú desplegable sería tan fácil como esto:
@Html.DropDownListFor(x => x.StateCode, from State state in Enum.GetValues(typeof(States)) select new SelectListItem() { Text = state.ToString(), Value = ((int)state).ToString() } );
¿No es LINQ bonito?
fuente
Pude hacer esto en una sola línea.
@Html.DropDownListFor(m=>m.YourModelProperty,new SelectList(Enum.GetValues(typeof(YourEnumType))))
fuente
Basado en la respuesta aceptada por @jgauffin, he creado mi propia versión de
EnumDropDownListFor
, que trata el problema de seleccionar elementos.El problema se detalla en otra respuesta SO aquí :, y se debe básicamente a un malentendido del comportamiento de las diferentes sobrecargas de
DropDownList
.Mi código completo (que incluye sobrecargas para
htmlAttributes
etc. es:public static class EnumDropDownListForHelper { public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression ) where TModel : class { return EnumDropDownListFor<TModel, TProperty>( htmlHelper, expression, null, null); } public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes ) where TModel : class { return EnumDropDownListFor<TModel, TProperty>( htmlHelper, expression, null, htmlAttributes); } public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes ) where TModel : class { return EnumDropDownListFor<TModel, TProperty>( htmlHelper, expression, null, htmlAttributes); } public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string optionLabel ) where TModel : class { return EnumDropDownListFor<TModel, TProperty>( htmlHelper, expression, optionLabel, null); } public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string optionLabel, IDictionary<string,object> htmlAttributes ) where TModel : class { string inputName = GetInputName(expression); return htmlHelper.DropDownList( inputName, ToSelectList(typeof(TProperty)), optionLabel, htmlAttributes); } public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string optionLabel, object htmlAttributes ) where TModel : class { string inputName = GetInputName(expression); return htmlHelper.DropDownList( inputName, ToSelectList(typeof(TProperty)), optionLabel, htmlAttributes); } private static string GetInputName<TModel, TProperty>( Expression<Func<TModel, TProperty>> expression) { if (expression.Body.NodeType == ExpressionType.Call) { MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body; string name = GetInputName(methodCallExpression); return name.Substring(expression.Parameters[0].Name.Length + 1); } return expression.Body.ToString() .Substring(expression.Parameters[0].Name.Length + 1); } private static string GetInputName(MethodCallExpression expression) { // p => p.Foo.Bar().Baz.ToString() => p.Foo OR throw... MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression; if (methodCallExpression != null) { return GetInputName(methodCallExpression); } return expression.Object.ToString(); } private static SelectList ToSelectList(Type enumType) { List<SelectListItem> items = new List<SelectListItem>(); foreach (var item in Enum.GetValues(enumType)) { FieldInfo fi = enumType.GetField(item.ToString()); var attribute = fi.GetCustomAttributes( typeof(DescriptionAttribute), true) .FirstOrDefault(); var title = attribute == null ? item.ToString() : ((DescriptionAttribute)attribute).Description; var listItem = new SelectListItem { Value = item.ToString(), Text = title, }; items.Add(listItem); } return new SelectList(items, "Value", "Text"); } }
He escrito esto en mi blog aquí .
fuente
Esto sería útil para seleccionar un valor int de enum: Aquí
SpecType
hay unint
campo ... yenmSpecType
es unenum
.@Html.DropDownList( "SpecType", YourNameSpace.SelectExtensions.ToSelectList(typeof(NREticaret.Core.Enums.enmSpecType), Model.SpecType.ToString()), "Tip Seçiniz", new { gtbfieldid = "33", @class = "small" })
fuente
Hice el siguiente cambio en el método SelectList para que funcione un poco mejor para mí. Quizás sea útil para otros.
public static SelectList ToSelectList<T>(T selectedItem) { if (!typeof(T).IsEnum) throw new InvalidEnumArgumentException("The specified type is not an enum"); var selectedItemName = Enum.GetName(typeof (T), selectedItem); var items = new List<SelectListItem>(); foreach (var item in Enum.GetValues(typeof(T))) { var fi = typeof(T).GetField(item.ToString()); var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault(); var enumName = Enum.GetName(typeof (T), item); var title = attribute == null ? enumName : ((DescriptionAttribute)attribute).Description; var listItem = new SelectListItem { Value = enumName, Text = title, Selected = selectedItemName == enumName }; items.Add(listItem); } return new SelectList(items, "Value", "Text"); }
fuente
public enum EnumStates { AL = 0, AK = 1, AZ = 2, WY = 3 } @Html.DropDownListFor(model => model.State, (from EnumStates e in Enum.GetValues(typeof(EnumStates)) select new SelectListItem { Value = ((int)e).ToString(), Text = e.ToString() }), "select", new { @style = "" }) @Html.ValidationMessageFor(model => model.State) //With select //Or @Html.DropDownListFor(model => model.State, (from EnumStates e in Enum.GetValues(typeof(EnumStates)) select new SelectListItem { Value = ((int)e).ToString(), Text = e.ToString() }), null, new { @style = "" }) @Html.ValidationMessageFor(model => model.State) //With out select
fuente
Igual que el de Mike (que está enterrado entre largas respuestas)
model.truckimagelocation es una propiedad de instancia de clase del tipo de enumeración TruckImageLocation
@Html.DropDownListFor(model=>model.truckimagelocation,Enum.GetNames(typeof(TruckImageLocation)).ToArray().Select(f=> new SelectListItem() {Text = f, Value = f, Selected = false}))
fuente
Este es el código más genérico que se utilizará para todas las enumeraciones.
public static class UtilitiesClass { public static SelectList GetEnumType(Type enumType) { var value = from e in Enum.GetNames(enumType) select new { ID = Convert.ToInt32(Enum.Parse(enumType, e, true)), Name = e }; return new SelectList(value, "ID", "Name"); } }
ViewBag.Enum= UtilitiesClass.GetEnumType(typeof (YourEnumType));
View.cshtml
@Html.DropDownList("Type", (IEnumerable<SelectListItem>)ViewBag.Enum, new { @class = "form-control"})
fuente
puedes usar enum en tu modelo
tu enumeración
public enum States() { AL,AK,AZ,...WY }
Haz un modelo
public class enumclass { public States statesprop {get; set;} }
en vista
fuente
La respuesta más fácil en MVC5 es Define Enum:
public enum ReorderLevels { zero = 0, five = 5, ten = 10, fifteen = 15, twenty = 20, twenty_five = 25, thirty = 30 }
Enlazar en vista:
<div class="form-group"> <label>Reorder Level</label> @Html.EnumDropDownListFor(m => m.ReorderLevel, "Choose Me", new { @class = "form-control" }) </div>
fuente