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.
Ne pouvez-vous pas juste l'attacher à un IEnumerable ou de la Liste de SelectListItems à la place?
OriginalL'auteur Dave Hanna | 2010-05-26
Vous devez vous connecter pour publier un commentaire.
Ici est une approche:
Notez que j'utilise ViewBag à contenir mon SelectList. De cette façon, lorsque vous postez, le client n'envoie pas l'ensemble de la liste de sélection jusqu'au serveur en tant que partie du modèle.
Dans votre contrôleur de code, il vous suffit de définir le point de vue du sac:
OriginalL'auteur Geoff Cox
Envisager la création d'un point de vue différent modèle pour votre post de l'action sans la SelectList propriété:
Ensuite, vous pouvez toujours la carte de la DemoCreateViewModelPost exemple à un DemoCreateViewModel exemple, si le modèle de l'état n'est pas valide et que vous voulez ré-afficher la vue. J'ai tendance à préférer tout ce qui est nécessaire à l'affichage d'être dans mon affichage de la classe du modèle, donc à l'aide d'une mise à jour séparée seulement de la vue modèle, laissez-moi garder les choses mince et pour le voyage de retour vers le serveur.
À votre avis, vous feriez:
comme dans la réponse précédente, donc pas de données inutiles serait aller-retour.
OriginalL'auteur gerrard00