2011-08-17 4 views
1

je modèle suivant (simplifié):ASP.NET MVC valeur Sélection de dropdownlist

public class CarType 
{ 
    public int Id { get; set; } 

    [Required] 
    public string Name { get; set; } 
} 

public class Car 
{ 
    [Required] 
    public string Model { get; set; } 

    [Required] 
    public CarType Type { get; set; } 

    [Required] 
    public decimal Price { get; set; } 
} 

Je veux permettre à l'utilisateur de choisir le type de véhicule dans la liste déroulante sur la page Créer. J'ai essayé de passer le dictionnaire des types de base de données et leurs noms par ViewBag:

ViewBag.Types = _context.CarTypes.ToDictionary(carType => carType.Name); 

et sélectionnez dans la page:

@Html.DropDownListFor(model => model.Type, new SelectList(ViewBag.Types, "Value", "Key")) 

Mais dans la méthode POST Je suis toujours construit objet Car avec null dans Type propriété.

[HttpPost] 
public ActionResult Create(Car car) 
{ 
    if (ModelState.IsValid) 
    { 
     _context.Cars.Add(car); 
     _context.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(car); 
} 

Est-il possible de sélectionner des objets personnalisés avec DropDownList? Parce que la sélection de valeurs comme int, string fonctionne très bien.

J'ai eu une idée d'écrire ViewModel avec int ID au lieu de CarType et trouver Type par ID avant d'enregistrer dans la base de données. Mais de cette façon, j'ai besoin de dupliquer toutes les propriétés Car et leurs attributs à mon ViewModel et à la fin - copier toutes les valeurs dans le nouvel objet Car. Pour une petite classe c'est peut-être OK, mais pour certains plus complexe - ne le pensez pas ...

Ceci est un petit exemple. Quelle est l'approche commune pour résoudre de tels problèmes? Comment écrire du code flexible et simple?

Répondre

1

est ici une méthode fidèle d'extension HtmlHelper J'utilise pour ces occassions:

public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, SelectListItem initialItem) 
    where TProperty : struct 
{ 
    if (!typeof(TProperty).IsEnum) 
     throw new ArgumentException("An Enumeration type is required.", "enum"); 

    IList<SelectListItem> items = Enum.GetValues(typeof(TProperty)).Cast<TProperty>() 
      .Select(t => new SelectListItem { Text = (t as Enum).GetDescription(), Value = t.ToString() }).ToList(); 

    if (initialItem != null) 
     items.Insert(0, initialItem); 

    return SelectExtensions.DropDownListFor<TModel, TProperty>(helper, expression, items, null, null); 
} 

qui vous permettra d'écrire du code comme ceci:

@Html.DropDownListForEnum(model => model.Type) 

Et vous donner un élément de sélection entièrement rempli avec le passé dans Type sélectionné.

La méthode ci-dessus peut être étendue avec htmlAttributes et tout le reste, mais il est un bon début

+0

Si je comprends bien, que cette méthode d'aide construit juste la liste des 'SelectListItem', remplir sa' Text' et 'valeur 'propriétés et faire' DropDownListFor' pour ma propriété? Le problème est que 'Value' est une chaîne. Donc, cette approche me retournera pas l'objet CarType null avec Id par défaut (0 pour int). Quand j'ai besoin d'avoir un objet CarType avec l'ID de la base de données. –

+0

J'ai vu que vous utilisiez une énumération 'CarType', donc c'était logique. Etes-vous en train de mapper vers votre table de base de données? Vous devriez toujours être capable de lancer cette énumération pour l'enregistrer comme un int. – hunter

Questions connexes