Html.EnumDropdownListFor: muestra un texto predeterminado

En mi opinión, tengo una lista enumdowndown (una nueva característica en Asp.Net MVC 5.1).

@Html.EnumDropDownListFor(m => m.SelectedLicense,new { @class="form-control"}) 

Si ejecuto el código anterior, obtengo una lista desplegable para mi siguiente enumeración.

 public enum LicenseTypes { Trial = 0, Paid = 1 } 

pero por defecto quiero que mi lista desplegable tenga un valor (texto personalizado) y esto es lo que probé

 @Html.EnumDropDownListFor(m => m.SelectedLicense,"Select a license" ,new { @class="form-control"}) 

pero ahora el problema es cuando lo ejecuto, mi lista desplegable se parece a esto enter image description here Por lo tanto, el texto predeterminado que quiero mostrar no aparece de forma predeterminada. Si un usuario selecciona “seleccionar una licencia” e intenta enviar el formulario, muestra un error que dice “seleccionar una licencia” pero no se muestra como texto predeterminado. Algo que necesito cambiar?

Ps: la imagen es la captura de pantalla de la página cuando se carga. Por defecto, mostrará la opción de prueba como seleccionada.

Intente cambiar el Index de LicenseTypes desde 1 no como el siguiente:

 public enum LicenseTypes { Trial = 1, Paid = 2 } 

Luego puede usar el Range attribute para validar el tipo de licencia seleccionado como se muestra a continuación:

 public class YourViewModel { //Other properties [Range(1,int.MaxValue,ErrorMessage = "Select a correct license")] public LicenseTypes LicenseTypes { get; set; } } 

Finalmente, en su opinión:

  @Html.EnumDropDownListFor(m => m.LicenseTypes,"Select a license",new { @class = "form-control"}) @Html.ValidationMessageFor(m => m.LicenseTypes) 

Para cuando se represente EnumDropDownListFor SelectedLicense ya tiene el valor predeterminado para el tipo, que es 0 .

Simplemente cambie el tipo de su propiedad SelectedLicense a una enumeración nullable, así:

 public LicenseTypes? SelectedLicense { get; set; } 

Esto también le permite continuar usando el atributo Required , que creo que es significativamente más limpio. El atributo Required no permitirá una respuesta nula, por lo tanto, aunque su modelo permita valores nulos, el formulario no lo hará.

Tengo una enumeración:

 public enum Sex { Male, Female } 

En mi modelo tengo:

  [DisplayName("Sex")] [Required] public Sex? Sex { get; set; } 

Un en la vista:

  @Html.EnumDropDownListFor(model => model.Sex, "Select sex", new { @class = "form-control", type = "text"}) 

Con esto, tengo un menú desplegable con la opción predeterminada “Seleccionar sexo”, pero la validación solo acepta las opciones proporcionadas por enum (“Hombre” y “Mujer”).

En MVC3 (sin EnumDropDownListFor) que utilicé en el modelo:

  [DisplayName("Sex")] [Required(AllowEmptyStrings=false)] public Sex? Sex { get; set; } Sex = null; Sexes = Repository.GetAutoSelectList(""); 

En vista:

  @Html.DropDownListFor(model => model.Sex, Model.Sexes, new { @class = "form-control", type = "text" }) 

La clase ViewModel necesita tener el valor predeterminado establecido en la propiedad enum para que sea el público seleccionado predeterminado

 public class Test { public Cars MyCars { get; set; } public enum Cars { [Display(Name = @"Car #1")] Car1 = 1, [Display(Name = @"Car #2")] Car2 = 2, [Display(Name = @"Car #3")] Car3 = 3 } } 

Controlador:

  public class EnumController : Controller { // GET: Enum public ActionResult Index() { var model = new Test {MyCars = Test.Cars.Car3}; // set default value return View(model); } [HttpPost] public ActionResult Index(Test model) { ..... } } 

Ver:

 @Html.BeginForm() { 
Enums
@Html.EnumDropDownListFor(model => model.MyCars)
}

¿Estoy un poco tarde?

Cambiar los valores del tipo enum no es muy satisfactorio.

Tampoco está cambiando la propiedad del modelo para convertirlo en nulo y luego agregar un atributo [Obligatorio] para evitar que sea nulo.

Propongo usar ViewBag para establecer el valor seleccionado predeterminado del menú desplegable. La línea 4 del controlador justo debajo es la única importante.

EDITAR: Ah … novatos … Mi primera idea fue usar ModelState.SetModelValue porque mi instinto de novato me impidió simplemente intentar establecer el valor deseado en ViewBag ya que el menú desplegable estaba vinculado al modelo. Estaba seguro de tener un problema: se uniría a la propiedad del modelo, no a la propiedad del ViewBag. Estaba equivocado: ViewBag está bien. Corregí el código.

Aquí hay un ejemplo.

Modelo:

 namespace WebApplication1.Models { public enum GoodMusic { Metal, HeavyMetal, PowerMetal, BlackMetal, ThashMetal, DeathMetal // . . . } public class Fan { [Required(ErrorMessage = "Don't be shy!")] public String Name { get; set; } [Required(ErrorMessage = "There's enough good music here for you to chose!")] public GoodMusic FavouriteMusic { get; set; } } } 

Controlador:

 namespace WebApplication1.Controllers { public class FanController : Controller { public ActionResult Index() { ViewBag.FavouriteMusic = string.Empty; //ModelState.SetModelValue( "FavouriteMusic", new ValueProviderResult( string.Empty, string.Empty, System.Globalization.CultureInfo.InvariantCulture ) ); return View( "Index" ); } [HttpPost, ActionName( "Index" )] public ActionResult Register( Models.Fan newFan ) { if( !ModelState.IsValid ) return View( "Index" ); ModelState.Clear(); ViewBag.Message = "OK - You may register another fan"; return Index(); } } } 

Ver:

 @model WebApplication1.Models.Fan 

Hello, fan

@using( Html.BeginForm() ) {

@Html.LabelFor( m => m.Name )

@Html.EditorFor( m => m.Name ) @Html.ValidationMessageFor( m => m.Name )

@Html.LabelFor( m => m.FavouriteMusic )

@Html.EnumDropDownListFor( m => m.FavouriteMusic, "Chose your favorite music from here..." ) @Html.ValidationMessageFor( m => m.FavouriteMusic )

@ViewBag.Message }

Sin la línea “ModelState.SetModelValue o ViewBag.FavouriteMusic = string.Empty” en la acción Index del modelo, el valor seleccionado por defecto sería “Metal” y no “Seleccionar su música …”