我想在一个视图中有2个模型。页面包含LoginViewModel和RegisterViewModel。

e.g.

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

我需要做另一个ViewModel持有这2个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)
 }

当前回答

我想说的是,我的解决方案就像这个stackoverflow页面上提供的答案:ASP。NET MVC 4,多个模型在一个视图?

然而,在我的情况下,他们在他们的控制器中使用的linq查询不适合我。

这就是所谓的查询:

var viewModels = 
        (from e in db.Engineers
         select new MyViewModel
         {
             Engineer = e,
             Elements = e.Elements,
         })
        .ToList();

因此,“在您的视图中,只需指定您正在使用视图模型的集合”对我来说也不适用。

然而,稍微改变一下这个解决方案确实对我有用。这是我的解决方案,希望对大家有所帮助。

这是我的视图模型,我知道我将只有一个团队,但该团队可能有多个板(顺便说一下,我在我的Models文件夹中有一个ViewModels文件夹,因此有命名空间):

namespace TaskBoard.Models.ViewModels
{
    public class TeamBoards
    {
        public Team Team { get; set; }
        public List<Board> Boards { get; set; }
    }
}

这是我的控制器。这是与上面引用的链接中的解决方案最显著的区别。我构建了ViewModel以不同的方式发送到视图。

public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            TeamBoards teamBoards = new TeamBoards();
            teamBoards.Boards = (from b in db.Boards
                                 where b.TeamId == id
                                 select b).ToList();
            teamBoards.Team = (from t in db.Teams
                               where t.TeamId == id
                               select t).FirstOrDefault();

            if (teamBoards == null)
            {
                return HttpNotFound();
            }
            return View(teamBoards);
        }

在我看来,我没有将它指定为列表。我只做@model taskboard。models。viewmodels。“然后,当我迭代团队的板时,我只需要每个。以下是我的观点:

@model TaskBoard.Models.ViewModels.TeamBoards

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
    <h4>Team</h4>
    <hr />


    @Html.ActionLink("Create New Board", "Create", "Board", new { TeamId = @Model.Team.TeamId}, null)
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => Model.Team.Name)
        </dt>

        <dd>
            @Html.DisplayFor(model => Model.Team.Name)
            <ul>
                @foreach(var board in Model.Boards)
                { 
                    <li>@Html.DisplayFor(model => board.BoardName)</li>
                }
            </ul>
        </dd>

    </dl>
</div>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.Team.TeamId }) |
    @Html.ActionLink("Back to List", "Index")
</p>

我对ASP还是个新手。NET MVC,所以我花了一点时间来弄清楚。所以,我希望这篇文章能帮助人们在更短的时间内为他们的项目找到答案。: -)

其他回答

使用包含多个视图模型的视图模型:

   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)

我想说的是,我的解决方案就像这个stackoverflow页面上提供的答案:ASP。NET MVC 4,多个模型在一个视图?

然而,在我的情况下,他们在他们的控制器中使用的linq查询不适合我。

这就是所谓的查询:

var viewModels = 
        (from e in db.Engineers
         select new MyViewModel
         {
             Engineer = e,
             Elements = e.Elements,
         })
        .ToList();

因此,“在您的视图中,只需指定您正在使用视图模型的集合”对我来说也不适用。

然而,稍微改变一下这个解决方案确实对我有用。这是我的解决方案,希望对大家有所帮助。

这是我的视图模型,我知道我将只有一个团队,但该团队可能有多个板(顺便说一下,我在我的Models文件夹中有一个ViewModels文件夹,因此有命名空间):

namespace TaskBoard.Models.ViewModels
{
    public class TeamBoards
    {
        public Team Team { get; set; }
        public List<Board> Boards { get; set; }
    }
}

这是我的控制器。这是与上面引用的链接中的解决方案最显著的区别。我构建了ViewModel以不同的方式发送到视图。

public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            TeamBoards teamBoards = new TeamBoards();
            teamBoards.Boards = (from b in db.Boards
                                 where b.TeamId == id
                                 select b).ToList();
            teamBoards.Team = (from t in db.Teams
                               where t.TeamId == id
                               select t).FirstOrDefault();

            if (teamBoards == null)
            {
                return HttpNotFound();
            }
            return View(teamBoards);
        }

在我看来,我没有将它指定为列表。我只做@model taskboard。models。viewmodels。“然后,当我迭代团队的板时,我只需要每个。以下是我的观点:

@model TaskBoard.Models.ViewModels.TeamBoards

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
    <h4>Team</h4>
    <hr />


    @Html.ActionLink("Create New Board", "Create", "Board", new { TeamId = @Model.Team.TeamId}, null)
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => Model.Team.Name)
        </dt>

        <dd>
            @Html.DisplayFor(model => Model.Team.Name)
            <ul>
                @foreach(var board in Model.Boards)
                { 
                    <li>@Html.DisplayFor(model => board.BoardName)</li>
                }
            </ul>
        </dd>

    </dl>
</div>
<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.Team.TeamId }) |
    @Html.ActionLink("Back to List", "Index")
</p>

我对ASP还是个新手。NET MVC,所以我花了一点时间来弄清楚。所以,我希望这篇文章能帮助人们在更短的时间内为他们的项目找到答案。: -)

我建议使用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将是位于当前View文件夹或共享文件夹中的用户控件,并像这样:

/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)
}

你有一个单独的控制器动作,每个动作都有视图和视图文件每个动作都完全不同,不依赖于其他任何东西。

有很多方法……

with your BigViewModel you do: @model BigViewModel @using(Html.BeginForm()) { @Html.EditorFor(o => o.LoginViewModel.Email) ... } you can create 2 additional views Login.cshtml @model ViewModel.LoginViewModel @using (Html.BeginForm("Login", "Auth", FormMethod.Post)) { @Html.TextBoxFor(model => model.Email) @Html.PasswordFor(model => model.Password) } and register.cshtml same thing after creation you have to render them in the main view and pass them the viewmodel/viewdata so it could be like this: @{Html.RenderPartial("login", ViewBag.Login);} @{Html.RenderPartial("register", ViewBag.Register);} or @{Html.RenderPartial("login", Model.LoginViewModel)} @{Html.RenderPartial("register", Model.RegisterViewModel)} using ajax parts of your web-site become more independent iframes, but probably this is not the case

在你的模型和LoginViewModel和RegisterViewModel属性中创建一个新类: 公共类UserDefinedModel() { 属性a1作为LoginViewModel property a2 as RegisterViewModel } 然后在视图中使用UserDefinedModel。