web-dev-qa-db-fra.com

ASP.NET MVC - Afficher avec plusieurs modèles

J'essaie de générer un tel HTML

    <form action="/some/process" method="post">
        <input type="hidden" name="foo.a" value="aaa"/>
        <input type="hidden" name="bar.b" value="bbb"/>
        <input type="submit" />
    </form>

afin qu'il puisse être traité par cette action:

    public ActionResult Process(Foo foo, Bar bar)
    {
        ...
    }

Étant donné le code d'action

    public ActionResult Edit()
    {
        ViewData["foo"] = new Foo { A = "aaa" };
        ViewData["bar"] = new Bar { B = "bbb" };

        return View();
    }

que dois-je écrire dans la vue Edit.aspx? Je ne veux pas écrire les noms 'foo.a' et 'bar.b' manuellement.

33
alex2k8

ViewData indexé par chaîne est mauvais. Ce que vous voulez probablement faire est de créer une petite classe wrapper pour vos données de vue à variables multiples et de la transmettre à une vue fortement typée. C'EST À DIRE:

public class FooBarViewData
{
   public Foo Foo {get; set;}
   public Bar Bar {get; set;}
}
public ActionResult Edit()
{
   FooBarViewData fbvd = new FooBarViewData();
   fbvd.Foo = new Foo(){ A = "aaa"};
   fbvd.Bar = new Bar(){ B = "bbb"};
   return View(fbvd);
}

Ensuite, votre vue est simplement saisie dans FooBarViewData et vous pouvez appeler les membres de cet objet à l'aide de la propriété Model.

40
Wyatt Barnett

Vous avez deux choix. Tout d'abord, vous pouvez les référencer depuis ViewData et utiliser une extension HtmlHelper. Vous pouvez également créer un modèle spécifique à une vue et utiliser une page d'affichage fortement typée pour Edit.aspx.

public class EditModel
{
    public Foo foo { get; set; }
    public Bar bar { get; set; }
}

public ActionResult Edit()
{
    var model = new EditModel();

    model.foo = new Foo { A = "aaa" };
    model.bar = new Bar { B = "bbb" };

    return View( model );
}

(Edit.aspx est de type ViewPage<EditModel>)

Quoi qu'il en soit, l'extension HtmlHelper prendra toutes les valeurs initiales.

<form action="/some/process" method="post">
     <%= Html.Hidden( "foo.A" ) %>
     <%= Html.Hidden( "bar.B" ) %>
</form>
10
tvanfosson

La solution ci-dessus peut être obsolète. Cette solution semble fonctionner pour ASP.Net MVC5 +.

Vous allez devoir utiliser la méthode ViewModel. C'est un excellent tutoriel que vous pouvez consulter.

http://tutlane.com/tutorial/aspnet-mvc/how-to-use-viewmodel-in-asp-net-mvc-with-example

Vous allez devoir joindre plusieurs modèles en une ViewModel et récupérer toutes les propriétés de chaque modèle que vous souhaitez utiliser dans la ViewModel.

MAIS, il est FORTEMENT conseillé de créer un nouveau contrôleur et un nouveau Voir pour accueillir le ViewModel nouvellement créé. Lire le tutoriel.

public class FooBarViewModel
{
   public string A {get; set;}  //Property for Foo
   public string B {get; set;}  //Property for Bar
}

public ActionResult Edit()
{
   FooBarViewModel fooBarVM = new FooBarViewModel();
   fooBarVM.A = "aaa";
   fooBarVM.B = "bbb";

   return View(fooBarVM);
}

Mais dans ce cas, vous devriez pouvoir passer la ViewModel dans une vue différente. Assurez-vous simplement de déclarer correctement cette directive similaire dans la page foobar.cshtml.

@model FooBar.Models.FooBarViewModel
0
David Lee

J'ai eu du mal à faire fonctionner deux modèles pendant un certain temps, et la plupart des réponses que j'ai trouvées étaient destinées aux versions précédentes de MVC.

J'ai trouvé que le tutoriel suivant fonctionne le mieux pour MVC 5 comme suggéré par David Lee :

http://tutlane.com/tutorial/aspnet-mvc/how-to-use-viewmodel-in-asp-net-mvc-with-example

J'ai créé une jointure et sélectionné uniquement les colonnes dont j'avais besoin dans les deux modèles.

Je l'avais travailler avec des vues partielles

Dans view.cshtml

 @model IEnumerable<Test.Models.TestViewModel>
    ...
      @foreach (var item in Model)
                    {
                        <tr>
                            <td style="text-align:center;vertical-align:middle">
                                @Html.DisplayFor(modelItem => item.TestName)
...
0
Abdul G