2011-04-05 67 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)放在保存/編輯塊的頂部。 。 。