[asp.net-mvc] 뷰에서 여러 모델

한 번에 두 가지 모델을 원합니다. 페이지가 모두 포함 LoginViewModel하고 RegisterViewModel.

예 :

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; }
}

이 2 개의 ViewModel을 보유하는 다른 ViewModel을 만들어야합니까?

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

뷰로 가져 오기 위해 유효성 검사 속성이 필요합니다. 이것이 ViewModels가 필요한 이유입니다.

(없이 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)
 }



답변

많은 방법이 있습니다 …

  1. BigViewModel을 사용하여 다음을 수행하십시오.

    @model BigViewModel
    @using(Html.BeginForm()) {
        @Html.EditorFor(o => o.LoginViewModel.Email)
        ...
    }
  2. 2 개의 추가보기를 만들 수 있습니다

    Login.cshtml

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

    register.cshtml 같은 것

    생성 후 메인 뷰에서 렌더링하고 뷰 모델 / 뷰 데이터를 전달해야합니다.

    따라서 다음과 같이 될 수 있습니다.

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

    또는

    @{Html.RenderPartial("login", Model.LoginViewModel)}
    @{Html.RenderPartial("register", Model.RegisterViewModel)}
  3. 웹 사이트의 아약스 부분을 사용하면 더 독립적이됩니다.

  4. iframes하지만 아마도 그렇지 않습니다.


답변

Html.RenderAction이를 위해 PartialViewResults를 사용하는 것이 좋습니다 . 동일한 데이터를 표시 할 수 있지만 각 부분 뷰에는 여전히 단일 뷰 모델이 있으며BigViewModel

따라서 뷰에는 다음과 같은 내용이 포함됩니다.

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

어디 Login&은 Register다음과 같이 정의 컨트롤러에서 모두 작업입니다 :

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

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

Login&는 Register다음, 또는 공유 폴더에 하나 현재보기 폴더에 존재하는 사용자 컨트롤 것과 같은 것을 좋아하는 것 :

/Views/Shared/Login.cshtml : (또는 /Views/MyView/Login.cshtml)

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

/Views/Shared/Register.cshtml : (또는 /Views/MyView/Register.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)
}

그리고 각 컨트롤러마다 하나의 컨트롤러 작업,보기 및보기 파일이 있습니다.


답변

다른 방법은 다음을 사용하는 것입니다.

@model Tuple<LoginViewModel,RegisterViewModel>

다른 예제를 위해 뷰와 컨트롤러에서이 방법을 사용하는 방법을 설명 했습니다. ASP MVC 3에서 한 뷰에 두 개의 모델

귀하의 경우 다음 코드를 사용하여 구현할 수 있습니다.

보기에서 :

@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"})
}

참고 양식을 구축 할 때 내가 수동으로 이름 변경 즉, 각 속성에 대한 속성. 이 작업을 수행해야합니다. 그렇지 않으면 값이 처리를 위해 관련 메서드로 전송 될 때 모델 형식의 메서드 매개 변수에 제대로 매핑되지 않습니다. 별도의 메소드를 사용하여 이러한 양식을 개별적으로 처리하는 것이 좋습니다.이 예에서는 Login1 및 Login2 메소드를 사용했습니다. Login1 메소드에는 RegisterViewModel 유형의 매개 변수가 필요하고 Login2에는 LoginViewModel 유형의 매개 변수가 필요합니다.

액션 링크가 필요한 경우 다음을 사용할 수 있습니다.

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

보기에 대한 컨트롤러의 메소드에서 Tuple 유형의 변수를 작성한 후보기로 전달해야합니다.

예:

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

또는 LoginViewModel 및 RegisterViewModel의 두 인스턴스를 값으로 채운 후보기로 전달할 수 있습니다.


답변

여러 뷰 모델이 포함 된 뷰 모델을 사용하십시오.

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

당신의 관점에서 :

  @model MyProject.Web.ViewModels.UserViewModel

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


답변

이 두 가지 견해를 보유하는 다른 견해를 만들어야합니까?

답변 : 아니요

(BigViewModel없이) 다른 방법이 없습니까?

, Tuple을 사용할 수 있습니다 (여러 모델의 관점에서 마술을 가져옵니다).

암호:

 @model Tuple<LoginViewModel, RegisterViewModel>


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


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


답변

이 ModelCollection.cs를 모델에 추가

using System;
using System.Collections.Generic;

namespace ModelContainer
{
  public class ModelCollection
  {
   private Dictionary<Type, object> models = new Dictionary<Type, object>();

   public void AddModel<T>(T t)
   {
      models.Add(t.GetType(), t);
   }

   public T GetModel<T>()
   {
     return (T)models[typeof(T)];
   }
 }
}

제어 장치:

public class SampleController : Controller
{
  public ActionResult Index()
  {
    var model1 = new Model1();
    var model2 = new Model2();
    var model3 = new Model3();

    // Do something

    var modelCollection = new ModelCollection();
    modelCollection.AddModel(model1);
    modelCollection.AddModel(model2);
    modelCollection.AddModel(model3);
    return View(modelCollection);
  }
}

보기:

enter code here
@using Models
@model ModelCollection

@{
  ViewBag.Title = "Model1: " + ((Model.GetModel<Model1>()).Name);
}

<h2>Model2: @((Model.GetModel<Model2>()).Number</h2>

@((Model.GetModel<Model3>()).SomeProperty


답변

그렇게하는 간단한 방법

우리는 모든 모델을 먼저 호출 할 수 있습니다

@using project.Models

그런 다음 뷰백으로 모델을 보내십시오.

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

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

그리고보기

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

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

그런 다음 모델처럼 쉽게 사용하십시오.