2016-12-27 1 views
2

J'essaie de modifier mon projet ASP.NET MVC à partir de vues et de modèles droits en utilisant une couche intermédiaire ViewModel. Fondamentalement, ce que je fais inclut avoir un Personne avec zéro ou plus Événements associés. Je suis en train de passer au ViewModel parce que je veux mettre une vue partielle sur la Personne Page de détails qui montre tous les événements associés .Comment configurer un ViewModel et une page partielle pour inclure un IEnumerable

J'ai une classe de modèle personne et un pour événement, ce qui est mon ViewModel:

public class PersonEventViewModel 
{ 
    public PersonEventViewModel(Person person) 
    { 
     Person = person; 
    } 

    public Person Person { get; set; } 
    public IEnumerable<Event> Events { get; set; } 

} 

Cela a bien fonctionné pour convertir mes simples pages d'enregistrement. Sur les pages telles que Person Details, je devais changer les lignes comme @Html.DisplayFor(model => model.CreatedOn) en @Html.DisplayFor(model => model.Person.CreatedOn) afin qu'il trouve les propriétés correctement, mais cela a fonctionné. Sur la vue partielle que j'essaie de faire, cependant, je n'arrive pas à les amener à montrer les propriétés du modèle. Il ressemble plus ou moins comme ceci:

@model IEnumerable<Proj.ViewModels.PersonEventViewModel> 

<table class="table"> 
    <tr> 
     <th>@Html.DisplayNameFor(model => model.RecordedOn)</th> 
     <th>@Html.DisplayNameFor(model => model.RecordedBy)</th> 
     <th>@Html.DisplayNameFor(model => model.Comments)</th> 
    </tr> 
@foreach (var item in Model) { 
    <tr> 
     <td>@Html.DisplayFor(modelItem => item.RecordedOn)</td> 
     <td>@Html.DisplayFor(modelItem => item.RecordedBy)</td> 
     <td>@Html.DisplayFor(modelItem => item.Comments)</td> 
    </tr> 
} 

Cela a fonctionné quand il utilisait le modèle des événements directement, mais maintenant il ne semble pas avoir d'importance ce que je mets entre model et la propriété, il me dit toujours que il ne peut pas le résoudre.

En outre, je ne suis pas sûr comment passer le ViewModel à la vue partielle. Je ne l'ai pas encore compris ce qu'il faut mettre ici:

@Html.RenderPartial("_PersonEventList", ?????) 

Mes diverses tentatives pour passer l'info modèle ou modèle ont tous été atteints avec des erreurs. Par demande, c'est la source de ma page de détails, où j'essaye de placer la vue partielle des événements.

@model Proj.ViewModels.PersonEventViewModel 
@{ ViewBag.Title = "Details"; } 
<h2>Details</h2> 
<div> 
    <h4>Person</h4> <hr/> 
    <dl class="dl-horizontal"> 
     <dt>@Html.DisplayNameFor(model => model.Person.FirstName)</dt> 
     <dd>@Html.DisplayFor(model => model.Person.FirstName)</dd> 
     @*...and so on through the fields...*@ 
    </dl> 
</div> 
<p> @Html.ActionLink("Edit Record", "Edit", new {id = Model.Person.PersonId}) </p> 

@Html.RenderPartial("_PersonEventList", Model) 
+0

Avez-vous essayé comme ça @ Html.RenderPartial ("_ PersonEventList", (Liste ) ViewBag.data) –

+0

Je n'avais pas , mais cela me donne toujours une erreur, semblable à ce qu'il a déjà dit: 'Impossible de convertir implicitement le type 'void' en 'object'. L'expression doit renvoyer une valeur à rendre. » – techturtle

+0

Essayez quelque chose comme ça, @ Html.Partial (" View ", Model); @ {Html.RenderPartial ("viewName", Model));} –

Répondre

0

En supposant que vous voulez "événements" dans votre partie, la partie devrait prendre un List<Event> car il est le modèle:

@model IEnumerable<Event> (or List<Event>) 

Puis dans votre vue principale:

@Html.RenderPartial("_PersonEventList", Model.Events) 
+0

Donc, partout où je lisais (SO et ailleurs) semble dire que des données comme celle-ci devraient être transmises via un ViewModel fortement typé, mais cela ressemble à ce que vous suggérez de revenir au modèle lui-même. Ou est-ce que je manque quelque chose? – techturtle

+0

En outre, j'ai essayé de passer à votre code suggéré, mais si j'utilise la commande 'RenderPartial', j'obtiens l'omniprésent' Impossible de convertir implicitement le type 'void' en 'object'' (ce qui ne me dit rien). Si je le laisse à '@ Html.Partial' alors ça semble être OK avec ça. Je n'ai pas été capable de comprendre pourquoi, mais comme je ne peux pas obtenir une vue partielle, je ne peux pas dire si cela fera une différence. – techturtle

+0

Que se passe-t-il lorsque vous faites juste @ Html.Partial ("_ PersonEventList", Model.Events)? –

0

Comme @Barry Franklin a déclaré, vous devriez changer votre partiel pour accepter une liste d'événements. Une autre chose que je voulais mentionner est que vous devriez probablement utiliser Partial et non RenderPartial. RenderPartial doit être placé entre parenthèses et avoir un; à la fin de celui-ci pour que cela fonctionne (Html.Partial vs Html.RenderPartial & Html.Action vs Html.RenderAction).

@Html.Partial("_PersonEventList", Model.Events) 

Vous devez également mettre à jour le code partiel:

@model IEnumerable<Proj.ViewModels.Event> 

<table class="table"> 
@foreach (var item in Model) { 
    <tr> 
     <td>@Html.DisplayFor(modelItem => item.RecordedOn)</td> 
     <td>@Html.DisplayFor(modelItem => item.RecordedBy)</td> 
     <td>@Html.DisplayFor(modelItem => item.Comments)</td> 
    </tr> 
} 
+0

Tout d'abord, '@model IEnumerable ' ne fonctionne pas car il n'y a pas de ViewModel appelé Event. Si je fais cela PersonEventViewModel, alors il est dit qu'il n'y a rien de ce qui s'appelle Event ou Events. Si je le fais Proj.Models.Event alors Visual Studio est tout à fait OK avec, et il semble même fonctionner correctement, jusqu'à ce que j'essaie d'afficher une page Détails. Puis il affiche l'erreur 'Impossible de créer une valeur constante de type 'Proj.Models.Person'. Seuls les types primitifs ou les types d'énumération sont pris en charge dans ce contexte. »Sur la ligne' @foreach (var item dans Model) {'. Aucune idée de ce que cette erreur signifie. – techturtle

+0

juste le remplacer par l'espace de noms que votre modèle d'événement habite –

+0

J'ai seulement ajouté que, par exemple, vous pouvez ajuster ce qui est nécessaire en fonction de votre projet –