ASP MVC 3中的一个视图中的两个模型

时间:2011-04-05 10:49:23

标签: asp.net-mvc-3 viewmodel

我有2个型号:

public class Person
{
    public int PersonID { get; set; }
    public string PersonName { get; set; }
}
public class Order
{
    public int OrderID { get; set; }
    public int TotalSum { get; set; }
}

我想在SINGLE视图中编辑BOTH类的对象,所以我需要这样的东西:

@model _try2models.Models.Person
@model _try2models.Models.Order

@using(Html.BeginForm())
{
    @Html.EditorFor(x => x.PersonID)
    @Html.EditorFor(x => x.PersonName)
    @Html.EditorFor(x=>x.OrderID)
    @Html.EditorFor(x => x.TotalSum)
}

当然,这不起作用:.cshtml文件中只允许一个'model'语句。可能有一些解决方法吗?

12 个答案:

答案 0 :(得分:109)

创建包含两种模型的父视图模型。

public class MainPageModel{
    public Model1 Model1{get; set;}
    public Model2 Model2{get; set;}
}

通过这种方式,您可以在以后轻松添加其他模型。

答案 1 :(得分:50)

要使用元组,您需要执行以下操作,在视图中将模型更改为:

@model Tuple<Person,Order>

要使用@html方法,您需要执行以下操作,例如:

@Html.DisplayNameFor(tuple => tuple.Item1.PersonId)

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

Item1表示传递给Tuple方法的第一个参数,您可以使用Item2访问第二个模型,依此类推。

在控制器中,您需要创建一个Tuple类型的变量,然后将其传递给视图:

    public ActionResult Details(int id = 0)
    {
        Person person = db.Persons.Find(id);
        if (person == null)
        {
            return HttpNotFound();
        }
        var tuple = new Tuple<Person, Order>(person,new Order());

        return View(tuple);
    }

另一个例子:Multiple models in a view

答案 2 :(得分:48)

另一个不需要创建自定义模型的选项是使用Tuple<>

@model Tuple<Person,Order>

根据Andi的回答,它并不像创建一个包含两者的新类一样干净,但它是可行的。

答案 3 :(得分:10)

如果您喜欢非常扁平的模型,只是为了支持视图,您应该创建特定于此特定视图的模型...

public class EditViewModel
    public int PersonID { get; set; }
    public string PersonName { get; set; }
    public int OrderID { get; set; }
    public int TotalSum { get; set; }
}

许多人使用AutoMapper从他们的域对象映射到他们的平面视图。

视图模型的想法是它只支持视图 - 没有别的。每个视图都有一个,以确保它只包含该视图所需的内容 - 而不是您希望其他视图加载的属性。

答案 4 :(得分:5)

好吧,每个人都有意义,我把所有的东西拿到这里,然后把它们放在这里帮助像我这样需要开始结束解释的新手。

根据@ Andrew的答案,你可以让你的大班上有两门课。

public class teamBoards{
    public Boards Boards{get; set;}
    public Team Team{get; set;}
}

然后在您的控制器中填写2个模型。有时你只需填一个。然后在返回时,您引用大型模型,它将内部的2带到视图。

            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();

 return View(teamBoards);

在视图的顶部

@model yourNamespace.Models.teamBoards

然后加载引用大型模型内容的输入或显示:

 @Html.EditorFor(m => Model.Board.yourField)
 @Html.ValidationMessageFor(m => Model.Board.yourField, "", new { @class = "text-danger-yellow" })

 @Html.EditorFor(m => Model.Team.yourField)
 @Html.ValidationMessageFor(m => Model.Team.yourField, "", new { @class = "text-danger-yellow" })

和。 。 。在牧场上,当邮报进来时,参考大班:

 public ActionResult ContactNewspaper(teamBoards teamboards)

并使用模型返回的内容:

string yourVariable = teamboards.Team.yourField;

可能在类中有一些DataAnnotation Validation内容,并且可能将if(ModelState.IsValid)放在save / edit块的顶部。 。 。

答案 5 :(得分:4)

实际上,有一种方法可以在一个视图上使用两个或更多模型,而不必将它们包装在包含两个模型的类中。

使用Employee作为示例模型:

@model Employee

实际上是对待的。

@{ var Model = ViewBag.model as Employee; }

因此,View(employee)方法将您的模型设置为ViewBag,然后ViewEngine正在投射它。

这意味着,

ViewBag.departments = GetListOfDepartments();
    return View(employee);

可以像,

一样使用
            @model  Employee
        @{
                var DepartmentModel = ViewBag.departments as List<Department>;
        }

基本上,您可以将ViewBag中的任何内容用作“模型”,因为无论如何它都是如此。我不是说这在建筑上是理想的,但它是可能的。

答案 6 :(得分:3)

只需创建一个包含所有必需信息的单一视图模型,通常我所做的是为每个视图创建一个模型,这样我就可以在每个视图上具体,或者创建父模型并继承它。或制作包含两种观点的模型。

就我个人而言,我只是将它们添加到一个模型中,但这就是我的方式:

public class xViewModel
{
    public int PersonID { get; set; }
    public string PersonName { get; set; }
    public int OrderID { get; set; }
    public int TotalSum { get; set; }
}

@model project.Models.Home.xViewModel

@using(Html.BeginForm())
{
    @Html.EditorFor(x => x.PersonID)
    @Html.EditorFor(x => x.PersonName)
    @Html.EditorFor(x => x.OrderID)
    @Html.EditorFor(x => x.TotalSum)
}

答案 7 :(得分:1)

您可以使用演示模式http://martinfowler.com/eaaDev/PresentationModel.html

此演示文稿“查看”模型可以包含Person和Order,这是新的 class可以是视图引用的模型。

答案 8 :(得分:0)

另一种从未谈过的方法是 在MSSQL中创建一个包含要呈现的所有数据的视图。然后使用LINQ to SQL或其他任何映射它。在您的控制器中将其返回到视图。完成。

答案 9 :(得分:0)

您无法在一个视图中声明两个模型,请尝试使用Html.Action("Person", "[YourController]")&amp; Html.Action("Order", "[YourController]")

祝你好运。

答案 10 :(得分:0)

除了asp.net中的一个视图模型外,您还可以制作多个局部视图并将不同的模型视图分配给每个视图,例如:

   @{
        Layout = null;
    }

    @model Person;

    <input type="text" asp-for="PersonID" />
    <input type="text" asp-for="PersonName" />

然后是订单模型的另一个局部视图模型

    @{
        Layout = null;
     }

    @model Order;

    <input type="text" asp-for="OrderID" />
    <input type="text" asp-for="TotalSum" />

然后在您的主视图中加载两个部分视图,

<partial name="PersonPartialView" />
<partial name="OrderPartialView" />

答案 11 :(得分:-1)

我希望你发现它有用!!

我使用ViewBag For Project和Model来执行任务,这样我就可以在单个视图中使用两个模型,在控制器中我定义了viewbag的值或数据

&#13;
&#13;
List<tblproject> Plist = new List<tblproject>();
            Plist = ps.getmanagerproject(c, id);

            ViewBag.projectList = Plist.Select(x => new SelectListItem
            {
                Value = x.ProjectId.ToString(),
                Text = x.Title
            });
&#13;
&#13;
&#13;

并且在视图中tbltask和projectlist是我的两个差异模型

@ {

IEnumerable<SelectListItem> plist = ViewBag.projectList;

} @model List