2011-04-05 46 views
86

我有2种型号:两款车型在ASP MVC一个视图3

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

我想在单一视图两个类的编辑对象,所以我需要的东西,如:

@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文件中只允许有一个“模型”语句。可能有一些解决方法?

+1

我的回答对你有帮助吗? – Andrew 2011-04-05 12:13:24

+0

我用'ViewBag'为每个视图为我工作,检查[this](http://www.codeproject.com/Articles/687061/Using-Multiple-Models-in-a-View-in-ASP- NET-MVC-M)知道多个选项,为我节省了很少的时间,而不是创建视图模型或局部视图 – stom 2015-04-13 17:46:26

回答

100

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

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

通过这种方式,您可以稍后添加其他型号,而且工作量极小。

+2

使用此解决方案时,请记住,对Model1或Model2的更改可能会对MainPageModel产生影响。它们主要包含比视图真正需要更多的数据。如果你的MainPage是已经存在于其他控制器中的东西的组合,从RenderPartial切换到RenderAction可以让你把东西整齐地分开。考虑阅读Demeter法:http://en.wikipedia.org/wiki/Law_of_Demeter – Fenton 2012-04-13 21:35:11

+0

@Andi - 我按照上面的建议创建了模型。但是当我右键点击控制器并尝试创建Crud控制器时,它不起作用?有什么建议么?我如何创建以上模型的自动视图crud控制器? – NoviceMe 2012-08-31 14:45:07

+2

在我看到解决这个问题的所有方法中,这是最适合我的方法。这是迄今为止最简单的解决方案。 – 2013-01-30 23:33:26

1

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

此演示文稿“视图”模式可同时包含人与秩序,这一新
类可以是模型视图引用。

+0

演示文稿模型实际上应包含所需的数据,这些数据可能来自Person和Order。它不应该包含Person或Order域对象。该视图将显示与底层域解耦。 – Fenton 2012-04-13 21:38:06

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从他们的域名映射对象的平面视图。

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

0

另一种永远不会被提及的方式是 在MSSQL中创建一个视图,其中包含要显示的所有数据。然后使用LINQ to SQL或其他来映射它。在您的控制器中将其返回到视图。完成。

47

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

@model Tuple<Person,Order> 

根据安迪的回答,它不像创建一个包含两者的新类,但它是可行的。

+0

在mvc 3中它给出错误文件中只允许有一个“模型”语句。任何想法如何解决它? – GibboK 2012-10-05 13:00:12

+1

@GibboK - 我在MVC3中使用它很好。确保你没有两个单独的'@ model'线? – Bobson 2012-10-05 13:20:34

+0

我现在得到它的工作,谢谢! – GibboK 2012-10-05 13:44:17

49

要使用你需要做以下的元组,在视图模式更改为:

@model Tuple<Person,Order> 

使用@html方法,你需要做以下即:

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

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

Item1指示传递给Tupel方法的第一个参数,您可以使用Item2来acc第二个模型等等。

在你的控制器,你需要创建一个元组类型的变量,然后将它传递给视图:

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

+0

**在这种情况下,从不**使用'Tuple' -OP想要编辑数据,而'Tuple'没有默认的构造函数,所以在提交表单时不能绑定模型 – 2017-10-19 07:37:57

0

你不能在一个视图中声明了两个模型,尝试使用Html.Action("Person", "[YourController]") & Html.Action("Order", "[YourController]")

祝你好运。

3

只需创建一个单一的视图模型中的所有需要​​的信息,normaly我做的是创造对每个视图模型,这样我就可以在特定的每个视图,要么或使父模型和继承它。或者制作一个包含两个视图的模型。

个人而言,我只想补充他们到一个模型,但是这就是我做的方式:

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

事实上,有使用在一个视图中的两个或多个模型,而不在类包装他们的方式,包含两者。

使用员工作为一个例子模型:

@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为“模型”,因为这是它是如何工作的呢。我并不是说这在架构上是理想的,但它是可能的。

-1

我希望你觉得它有帮助!

我使用ViewBag项目和模型的任务,以便通过这种方式,我使用的单一视图和控制器两型我定义viewbag的价值或数据

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

,并考虑tbltask和projectlist是我的两个差异模型

@ {

IEnumerable<SelectListItem> plist = ViewBag.projectList; 

} @model列表

2

OK,大家都在做的意义,我把所有的碎片,把它们放在这里是为了帮助新手喜欢自己,需要从头到尾解释。

你让你的大类,用于保存2班,按@安德鲁的回答。

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

和。 。 。 .back在牧场,当邮政进来,引用大类:

public ActionResult ContactNewspaper(teamBoards teamboards) 

和使用什么样的模式(S)返回:

string yourVariable = teamboards.Team.yourField; 

可能有一些DataAnnotation验证的东西该类可能会将(ModelState.IsValid)放在保存/编辑块的顶部。 。 。