303 votes

Plusieurs modèles dans une vue

Je veux avoir 2 modèles dans une vue. La page contient à la fois LoginViewModel et RegisterViewModel .

Par exemple.

 public class LoginViewModel
{
    public string Email { get; set; }
    public string Password { get; set; }
}

public class RegisterViewModel
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
}
 

Ai-je besoin de faire une autre vue qui détient ces 2 vues?

 public BigViewModel
{
    public LoginViewModel LoginViewModel{get; set;}
    public RegisterViewModel RegisterViewModel {get; set;}
}
 

J'ai besoin que les attributs de validation soient présentés à la vue, c'est pourquoi j'ai besoin des ViewModels.

N'y at-il pas un autre moyen tel que (sans le BigViewModel ):

  @model ViewModel.RegisterViewModel
 @using (Html.BeginForm("Login", "Auth", FormMethod.Post))
 {
        @Html.TextBoxFor(model => model.Name)
        @Html.TextBoxFor(model => model.Email)
        @Html.PasswordFor(model => model.Password)
 }

 @model ViewModel.LoginViewModel
 @using (Html.BeginForm("Login", "Auth", FormMethod.Post))
 {
        @Html.TextBoxFor(model => model.Email)
        @Html.PasswordFor(model => model.Password)
 }
 

261voto

Omu Points 17372

Il ya beaucoup de façons...

  1. avec votre BigViewModel vous n':

    @model BigViewModel    
    @using(Html.BeginForm()) {
        @Html.EditorFor(o => o.LoginViewModel.Email)
        ...
    }
    
  2. vous pouvez créer 2 autres points de vue

    Connexion.cshtml

    @model ViewModel.LoginViewModel
    @using (Html.BeginForm("Login", "Auth", FormMethod.Post))
    {
        @Html.TextBoxFor(model => model.Email)
        @Html.PasswordFor(model => model.Password)
    }
    

    et inscrivez-vous.cshtml même chose

    après la création vous devez vous rendre dans la vue principale et de les transmettre le viewmodel/viewdata

    ainsi, il pourrait être comme ceci:

    @{Html.RenderPartial("login", ViewBag.Login);}
    @{Html.RenderPartial("register", ViewBag.Register);}
    

    ou

    @{Html.RenderPartial("login", Model.LoginViewModel)}
    @{Html.RenderPartial("register", Model.RegisterViewModel)}
    
  3. à l'aide d'ajax parties de votre site web devient plus indépendant

  4. iframes, mais probablement ce n'est pas le cas

127voto

Thechoyce Points 1805

Je vous recommande d'utiliser Html.RenderAction et PartialViewResults de le réaliser; il vous permettra d'afficher les mêmes données, mais chaque vue partielle aurait encore un seul modèle de vue et élimine le besoin d'un BigViewModel

Donc, votre point de vue contenir quelque chose comme ce qui suit:

@Html.RenderAction("Login")
@Html.RenderAction("Register")

Login & Register sont à la fois des actions dans votre contrôleur défini comme suit:

public PartialViewResult Login( )
{
    return PartialView( "Login", new LoginViewModel() );
}

public PartialViewResult Register( )
{
    return PartialView( "Register", new RegisterViewModel() );
}

L' Login & Register seraient alors les contrôles de l'utilisateur, résidant dans la Vue dossier, ou dans le dossier Partagé et voudrais quelque chose comme ceci:

/Views/Shared/Login.cshtml: (ou /Vues/Mavue/Login.cshtml)

@model LoginViewModel
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
    @Html.TextBoxFor(model => model.Email)
    @Html.PasswordFor(model => model.Password)
}

/Views/Shared/Enregistrer.cshtml: (ou /Vues/Mavue/s'Inscrire.cshtml)

@model ViewModel.RegisterViewModel
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
    @Html.TextBoxFor(model => model.Name)
    @Html.TextBoxFor(model => model.Email)
    @Html.PasswordFor(model => model.Password)
}

Et là, vous avez un seul contrôleur de l'action, d'afficher et de visualiser un fichier pour chaque action, à chaque totalement distincts et ne dépendant pas de l'une sur l'autre pour rien.

113voto

Hamid Points 921

Une autre façon est d'utiliser:

@model Tuple<LoginViewModel,RegisterViewModel>

J'ai expliqué comment utiliser cette méthode à la fois dans la vue et le contrôleur pour un autre exemple: Deux modèles dans une vue en ASP net MVC 3

Dans votre cas vous pouvez le mettre en œuvre en utilisant le code suivant:

Dans la vue:

@using YourProjectNamespace.Models;
@model Tuple<LoginViewModel,RegisterViewModel>

@using (Html.BeginForm("Login1", "Auth", FormMethod.Post))
{
        @Html.TextBoxFor(tuple => tuple.Item2.Name, new {@Name="Name"})
        @Html.TextBoxFor(tuple => tuple.Item2.Email, new {@Name="Email"})
        @Html.PasswordFor(tuple => tuple.Item2.Password, new {@Name="Password"})
}

@using (Html.BeginForm("Login2", "Auth", FormMethod.Post))
{
        @Html.TextBoxFor(tuple => tuple.Item1.Email, new {@Name="Email"})
        @Html.PasswordFor(tuple => tuple.Item1.Password, new {@Name="Password"})
}

Note que j'ai modifié manuellement le Nom des attributs pour chaque propriété lors de la construction de la forme. Ce qui doit être fait, sinon il ne serait pas correctement mappé à la méthode du paramètre de type de modèle lorsque les valeurs sont transmises à la méthode associée à la transformation. Je suggère d'utiliser d'autres méthodes pour traiter ces formes séparément, pour cet exemple j'ai utilisé Login1 et Login2 méthodes. Login1 méthode nécessite d'avoir un paramètre de type RegisterViewModel et Login2 nécessite un paramètre de type LoginViewModel.

si un actionlink est nécessaire, vous pouvez utiliser:

@Html.ActionLink("Edit", "Edit", new { id=Model.Item1.Id })

dans la méthode du contrôleur de la vue, une variable de type Tuple doit être créé et ensuite passé à la vue.

Exemple:

public ActionResult Details()
{
    var tuple = new Tuple<LoginViewModel, RegisterViewModel>(new LoginViewModel(),new RegisterViewModel());
    return View(tuple);
}

ou, vous pouvez remplir les deux instances de LoginViewModel et RegisterViewModel avec les valeurs et puis la passer à la vue.

28voto

Yini Yin Points 75

Utilisateur un modèle de vue qui contient plusieurs modèles de vue:

    namespace MyProject.Web.ViewModels
   {
      public class UserViewModel
      {
          public UserDto User { get; set; }
          public ProductDto Product { get; set; }
          public AddressDto Address { get; set; }
      }
   }
 

À votre avis:

   @model vDieu.Web.ViewModels.UserViewModel

  @Html.LabelFor(model => model.User.UserName)
  @Html.LabelFor(model => model.Product.ProductName)
  @Html.LabelFor(model => model.Address.StreetName)
 

6voto

Pnsadeghy Points 362

un moyen simple de le faire

nous pouvons appeler tous les modèles d'abord

 @using project.Models
 

puis envoyez votre modèle avec vue

 // for list
ViewBag.Name = db.YourModel.ToList();

// for one
ViewBag.Name = db.YourModel.Find(id);
 

et en vue

 // for list
List<YourModel> Name = (List<YourModel>)ViewBag.Name ;

//for one
YourModel Name = (YourModel)ViewBag.Name ;
 

alors facilement l'utiliser comme modèle

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X