La liaison à un SelectList en MVC

Encore une fois, je suis confronté à un "Cela ne devrait pas être présent ?*!# dur" de la situation.

Problème: je veux utiliser un formulaire en MVC pour la création d'un objet. L'un des éléments de l'objet est un ensemble de choix limités - un candidat parfait pour une liste déroulante.

Mais si j'utilise un SelectList dans mon modèle, et une liste déroulante dans mon point de Vue, et puis essayer de poster le Modèle de retour à ma méthode de création, je reçois le message d'erreur "Manque de Méthode Exception:Pas de constructeur sans paramètre pour cet objet". Exploration de la MVC du code source, il apparaît que, dans le but de se lier à un modèle, le Liant doit être en mesure de créer tout d'abord, et il ne peut pas créer un SelectList car il n'y a pas de constructeur par défaut.

Voici le code simplifié:
Pour le modèle:

public class DemoCreateViewModel
{
    public SelectList Choice { get; set; }
}

Pour le contrôleur:

//
//GET: /Demo/Create

public ActionResult Create()
{
    DemoCreateViewModel data = new DemoCreateViewModel();
    data.Choice = new SelectList(new string[] { "Choice1", "Choice2", "Choice3" });
    ViewData.Model = data;
    return View();
}

//
//POST: /Demo/Create

[HttpPost]
public ActionResult Create(DemoCreateViewModel form)
{
    try
    {
        //TODO: Add insert logic here

        return RedirectToAction("Index");
    }
    catch
    {
        return View();
    }
}

Et pour la Vue:

<fieldset>
    <legend>Fields</legend>
    <%= Html.LabelFor(model => model.Choice) %>
    <%= Html.DropDownListFor(model => model.Choice, Model.Choice) %>
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>

Maintenant, je sais que je peux FAIRE ce travail par une baisse de 10 mètres et les barques à fond plat: bypass modèle de liaison et de revenir à la FormCollection et de le valider et de le lier tous les champs de moi-même, mais il doit y avoir un moyen plus simple. Je veux dire, c'est simple une exigence qu'il obtient. Est-il un moyen de faire ce travail au sein de la MVC ModelBinding architecture? Si oui, quel est-il? Et si non, comment venir?

Edit: bon, j'ai oeuf sur mon visage, mais peut-être que cela aidera quelqu'un d'autre. J'ai fait un peu plus à expérimenter et trouvé une solution qui semble fonctionner.

Fournir une valeur simple (string ou integer, selon ce que votre liste de sélection type de valeur est), et le nom que comme l'élément de modèle que vous liez. Ensuite, une deuxième élément de la liste de sélection de choix, et le nom de quelque chose d'autre. Donc, mon modèle est devenu:

public class DemoCreateViewModel
{
    public string Choice { get; set; }
    public SelectList Choices { get; set; }
}

Et puis le DropDownListFor instruction dans l'Affichage devient:

<%= Html.DropDownListFor(model => model.Choice, Model.Choices) %>

Quand je fais cela, le bouton soumettre correctement lie le choix fait dans le formulaire de la chaîne de Choix, et soumet le modèle vers la deuxième méthode de création.

Merci pour l'affichage de votre correction, j'ai eu un problème similaire et votre modifier aidé
Ne pouvez-vous pas juste l'attacher à un IEnumerable ou de la Liste de SelectListItems à la place?

OriginalL'auteur Dave Hanna | 2010-05-26