2010-12-01 6 views
3

Le modèle que je vois dans la majorité des exemples .NET MVC consiste à faire en sorte que votre modèle soit l'objet passé entre le contrôleur et les couches inférieures et à se lier directement à ceux-ci. J'ai opté pour une approche domain-driven où j'ai des objets de domaine passés entre les couches. L'idée était que ces objets seraient passés dans les vues.Formulaires MVC .NET avec une conception pilotée par domaine

Le problème que je rencontre est quand il s'agit de pages avec des formulaires. J'avais l'intention d'avoir des objets séparés pour les formulaires à lier au retour (qui contiendraient aussi les annotations de validation). Je gardais cela séparé de l'objet domaine car un seul objet pouvait éventuellement être mis à jour par différentes pages, chaque page ayant ses propres exigences de validation (par exemple, l'adresse d'une personne pourrait ne pas être affichée sur une page, mais nécessaire sur une autre, la validation ne fonctionnerait pas toujours sur l'objet de domaine universel). Cela complique les choses une fois que vous postez le formulaire et que vous avez besoin d'afficher des erreurs.

Prenez par exemple une page de mise à jour. Je tapais la vue à mon objet de domaine de domaine et la page aurait ses valeurs de champ peuplées de cela. L'action de publication prend l'objet de formulaire pour cette page et valide cela. Si elle est passée, j'utilise automapper pour copier les valeurs dans l'objet domaine du formulaire et enregistrer. Tout cela fonctionne. En cas de panne, elle réaffiche cette page en cas d'erreur. Si elle est tapée dans l'objet de domaine, je finirais par repeupler les champs en fonction des anciennes valeurs au lieu des valeurs entrées par l'utilisateur. Si elle est tapée dans l'objet formulaire, je dois traduire tous les objets de mon domaine pour ces objets de formulaire pour chaque page (et éventuellement passer dans l'objet domaine si j'ai besoin de valeurs que j'utiliserais en lecture seule pour cette page).

Je suis sûr que je suis en train de négliger/compliquer quelque chose ici.

Mise à jour Une trouvaille intéressante après avoir joué autour de cause de ce que dit @Charlino. Si j'ai utilisé les helpers html fortement typés pour faire les entrées (Html.TextBoxFor()), il se souviendra des valeurs même si la vue est tapée sur l'objet du domaine. Si j'utilise les génériques (Html.TextBox()) ou HTML brut cela ne semble pas le cas.

+0

Votre "objet de formulaire" est-il également un objet Personne? Si oui, renvoyez simplement cela à la vue. – Paul

+0

@paul L'objet formulaire est un sous-ensemble de l'objet personne - seulement les champs que je souhaite recevoir par HTTP Post et que je veux valider. – Parrots

+0

Avez-vous réellement implémenté ceci? Parce que, d'après ce que j'ai compris, lorsque vous ré-affichez la page, elle devrait vérifier ViewState pour repeupler les champs et ne devrait pas utiliser les objets de domaine. D'un côté, je suis d'accord avec l'approche de @ qstarin mais je suis aussi d'accord avec le commentaire de @ jfar. – Charlino

Répondre

3

Avoir un objet ViewModel pour chaque vue est ce que je finis par faire.

C'est un peu plus de travail à l'avance, car je dois définir le ViewModel et le mapping, mais ce code est si simple et direct qu'il ne faut que quelques secondes pour écrire.

Souvent, lorsque j'ai besoin d'un formulaire, je crée un objet Form distinct et le ViewModel le contient.

public class MyViewModel 
{ 
    public string SomeNonFormDisplayValue { get; set; } 
    public bool AnotherDisplayOnlyValue { get; set; } 
    public IEnumerable<Tuple<int, string>> SelectionListItems { get; set; } 

    public MyViewsForm Form { get; set; } 
} 


public class MyViewsForm 
{ 
    public string EditableProperty { get; set; } 
    public int SelectionListItemId { get; set; } 
} 

Je tape ma vue sur le ViewModel, mais je fais que la méthode Post Action prenne juste la forme.

public class MyController 
{ 
    [HttpGet] 
    public ActionResult Edit() { ... } 

    [HttpPost] 
    public ActionResult Edit(MyViewsForm form) { ... } 
} 

Je fais aussi des méthodes de requête pour récupérer le ViewModel, qui remplit la forme et une autre qui ne fonctionne pas - quand je retourne le formulaire POST'd avec des erreurs.

+0

Voter pour la technique mais avec la prudence qu'un objet de formulaire dans le ViewModel est inutile et trop compliqué. – jfar

+0

J'ai essayé les deux manières et je préfère l'objet forme imbriqué. Qu'est-ce qui est compliqué à ce sujet? C'est seulement une classe supplémentaire avec rien de plus que des getters de propriété et des setters. Et je trouve que cela aide à éliminer toute confusion liée à la publication d'un objet qui n'est qu'à moitié nécessaire. –

+0

Je suis aussi d'accord avec cette technique et je suis aussi un peu d'accord avec le commentaire de @ jfar. J'ai l'habitude d'avoir mes modèles de formulaire à l'intérieur de mes modèles de vue, mais a changé la nuit dernière et il semble que certaines chaînes ont été brisées. – Charlino

Questions connexes