web-dev-qa-db-fra.com

Html.EnumDropdownListFor: Afficher un texte par défaut

À mon avis, j'ai un enumdropdownlist (une nouvelle fonctionnalité de Asp.Net MVC 5.1).

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

Si j'exécute le code ci-dessus, j'obtiens une liste déroulante pour mon enum suivant.

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

mais par défaut je veux que ma liste déroulante ait une valeur (texte personnalisé) et c'est ce que j'ai essayé

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

mais maintenant le problème est que quand je le lance, ma liste déroulante ressemble à ceci enter image description here Ainsi, le texte par défaut que je veux montrer n'apparaît pas par défaut . Si un utilisateur sélectionne "sélectionner une licence" et essaie de soumettre le formulaire, il affiche une erreur disant "sélectionnez une licence", mais il ne montre pas que le texte par défaut . Quelque chose que je dois changer?

Ps: L'image est la capture d'écran de la page lors du chargement. Par défaut, l'option d'essai est sélectionnée.

59
Cybercop

Essayez de changer la Index de LicenseTypes à partir de 1 pas 0 comme ci-dessous:

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

Ensuite, vous pouvez utiliser Range attribute pour valider le type de licence sélectionné, comme ci-dessous:

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

Enfin, à votre avis:

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

Au moment où votre EnumDropDownListFor est rendu, SelectedLicense a déjà la valeur par défaut pour le type, qui est 0

Changez simplement le type de votre propriété SelectedLicense en une énumération nullable, comme ceci:

public LicenseTypes? SelectedLicense { get; set; }

Cela vous permet également de continuer à utiliser l'attribut Required, ce qui, à mon avis, est nettement plus net. L'attribut Required n'autorisera pas une réponse null. Ainsi, même si votre modèle autorise les valeurs NULL, le formulaire ne le permet pas.

63
Michael Richardson

J'ai un enum:

public enum Sex
{
    Male,
    Female
}

Dans mon modèle j'ai:

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

Un dans la vue:

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

Par cela, j'ai un menu déroulant avec l'option par défaut "Choisir le sexe", mais la validation accepte uniquement les options fournies par enum ("Homme" et "Femme").

Dans MVC3 (sans EnumDropDownListFor), j'ai utilisé dans le modèle:

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

    Sex = null;

    Sexes = Repository.GetAutoSelectList<Sex>("");

En vue:

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

La valeur par défaut de la classe ViewModel doit être définie sur la propriété enum pour qu'elle soit sélectionnée par défaut Public 

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
        }

    }

Manette:

 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)
        {
            .....
        }
    }

Vue:

@Html.BeginForm()
{
<div class="panel bg-white">
    <div class="panel-header fg-white">
        Enums
    </div>
    <div class="panel-content">
        <div class="input-control select size3">
            @Html.EnumDropDownListFor(model => model.MyCars)

        </div>
    </div>
    <input type="submit" class="button success large" />
</div>
}
8
Haroon

Suis-je un peu en retard?

Changer les valeurs du type enum n'est pas très satisfaisant.

Ni changer la propriété de modèle pour la rendre nullable, puis ajouter un attribut [Required] pour l'empêcher d'être nullable.

Je propose d’utiliser le ViewBag pour définir la valeur sélectionnée par défaut du menu déroulant .La ligne 4 du contrôleur ci-dessous est la seule qui soit importante.

EDIT: Ah ... les débutants ... Ma première idée était d'utiliser ModelState.SetModelValue car mon instinct de débutant m'empêchait d'essayer simplement de définir la valeur souhaitée dans le ViewBag puisque la liste déroulante était liée au modèle. J'étais sûr d'avoir un problème: cela lierait à la propriété du modèle, pas à la propriété du ViewBag. J'avais tout faux: ViewBag est OK. J'ai corrigé le code.

Voici un exemple.

Modèle:

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; }
    }
}

Manette:

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();
        }
    }
}

Vue:

@model WebApplication1.Models.Fan
<h2>Hello, fan</h2>
@using( Html.BeginForm() ) {
    <p>@Html.LabelFor( m => m.Name )</p>
    <p>@Html.EditorFor( m => m.Name ) @Html.ValidationMessageFor( m => m.Name )</p>
    <p>@Html.LabelFor( m => m.FavouriteMusic )</p>
    <p>@Html.EnumDropDownListFor( m => m.FavouriteMusic, "Chose your favorite music from here..." ) @Html.ValidationMessageFor( m => m.FavouriteMusic )</p>
    <input type="submit" value="Register" />
    @ViewBag.Message
}

Sans la ligne "ModelState.SetModelValue ou ViewBag.FavouriteMusic = string.Empty" dans l'action Index du modèle, la valeur sélectionnée par défaut serait "Metal" et non "Sélectionnez votre musique ..."

0
Rikou