[英]Multiple Models in a Single View (C# MVC3)
我正在使用C#和MVC3。
我有一個頁面,例如學生列表,顯示學生列表,這是由數據庫驅動的。 同時我的菜單是數據庫驅動的,所以我也必須將它發送到視圖。
如何將兩個模型發送到單個視圖?
您應始終為視圖創建單獨的ViewModel。 您的視圖應該從您的域模型中抽象出來。 在演示/教程中,他們通過簡單地強烈鍵入視圖到域模型來顯示它非常簡單,但這不是一個好策略。 視圖不應該依賴於業務對象。
即使需要將域模型映射到另一個視圖模型類,您也應該為當前場景以及所有其他視圖實現David Glenn提出的解決方案。
編輯:
如果你已經可以說頂部菜單> TopMenu.aspx
而你在它里面>多個部分觀點StudentMenu.ascx
, ResultMenu.ascx
您將創建頂級菜單>視圖模型TopMenuViewModel.cs
,你也將創建局部視圖>視圖模型StudentMenuViewModel
, ResultMenuViewModel
等。
並且您的TopMenuViewModel將具有兩個>
class TopMenuViewModel
{
//all the stuff required in TopMenu.aspx
StudentMenuViewModel studentvm;
ResultMenuViewModel resultvm;
}
在TopMenu.aspx
渲染局部時,您將傳遞相關的視圖模型>
Html.RenderPartial('StudentView', Model.studentvm)
希望它有意義
您可以創建一個ViewModel,它代表您的視圖,而不是您的業務模型
public class StudentPage {
public IEnumerable<Student> Students { get; set; }
public Menu Menu { get; set; }
}
然后,您的控制器將ViewModel返回到您的視圖
public ViewResult Students() {
var menu = GetMenu();
var students = Repository.Students();
var model = new StudentPage {
Menu = menu,
Students = students
}
return View(model);
}
我假設菜單是你網頁上的一個重復出現的功能,所以你可能想要分解它
public class BasePage {
public Menu Menu { get; set; }
}
public class StudentPage : BasePage {
public IEnumerable<Student> Students { get; set; }
}
您還可以創建一個具有GetMenu()
功能的基本控制器,以便在多個控制器之間重用。
注意 :下面的類應該在.net 3.5及更低版本中使用,因為.net 4作為類似的類引入,稱為
Tuple
,應該使用它。
MultiObject<O1, O2, ..>
和MultiList<L1, L2, ...>
這是我編寫這樣的控制器動作和視圖的方式:
public ActionResult MultiModel()
{
MultiList<User, Company> result = MultiList.New(
this.repository.GetUsers(),
this.repository.GetCompanies()
);
return View(result);
}
我的觀點是:
ViewPage<MultiList<User, Company>>
我正在使用這個可重用的便利類:
#region MultiObject static helper class
/// <summary>
/// Provides static methods for creating multi objects with type inference.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi")]
public static class MultiObject
{
/// <summary>
/// Creates a new <see cref="MultiObject{T1, T2}"/> object instance.
/// </summary>
/// <typeparam name="T1">The type of the first object.</typeparam>
/// <typeparam name="T2">The type of the second object.</typeparam>
/// <param name="first"><typeparamref name="T1"/> object instance.</param>
/// <param name="second"><typeparamref name="T2"/> object instance.</param>
/// <returns>
/// Returns a <see cref="MultiObject{T1, T2}"/> of <typeparamref name="T1"/> and <typeparamref name="T2"/> object instances.
/// </returns>
public static MultiObject<T1, T2> New<T1, T2>(T1 first, T2 second)
{
return new MultiObject<T1, T2>(first, second);
}
/// <summary>
/// Creates a new <see cref="MultiObject{T1, T2, T3}"/> object instance.
/// </summary>
/// <typeparam name="T1">The type of the first object.</typeparam>
/// <typeparam name="T2">The type of the second object.</typeparam>
/// <typeparam name="T3">The type of the third object.</typeparam>
/// <param name="first"><typeparamref name="T1"/> object instance.</param>
/// <param name="second"><typeparamref name="T2"/> object instance.</param>
/// <param name="third"><typeparamref name="T3"/> object instance.</param>
/// <returns>
/// Returns a <see cref="MultiObject{T1, T2, T3}"/> of <typeparamref name="T1"/>, <typeparamref name="T2"/> and <typeparamref name="T3"/> objects instances.
/// </returns>
public static MultiObject<T1, T2, T3> New<T1, T2, T3>(T1 first, T2 second, T3 third)
{
return new MultiObject<T1, T2, T3>(first, second, third);
}
}
#endregion
#region MultiObject<T1, T2>
/// <summary>
/// Represents a 2-multi object, or pair.
/// </summary>
/// <typeparam name="T1">The type of the multi object's first component.</typeparam>
/// <typeparam name="T2">The type of the multi object's second component.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi")]
public class MultiObject<T1, T2>
{
/// <summary>
/// Gets or sets the value of the first multi object component.
/// </summary>
/// <value>The first.</value>
public T1 First { get; set; }
/// <summary>
/// Gets or sets the value of the second multi object component.
/// </summary>
/// <value>The second multi object component value.</value>
public T2 Second { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MultiObject{T1, T2}"/> class.
/// </summary>
/// <param name="first">Multi object's first component value.</param>
/// <param name="second">Multi object's second component value.</param>
public MultiObject(T1 first, T2 second)
{
this.First = first;
this.Second = second;
}
}
#endregion
#region MultiObject<T1, T2, T3>
/// <summary>
/// Creates a new 3-multi object, or triple.
/// </summary>
/// <typeparam name="T1">The value of the first component of the multi object.</typeparam>
/// <typeparam name="T2">The value of the second component of the multi object.</typeparam>
/// <typeparam name="T3">The value of the third component of the multi object.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi")]
[SuppressMessage("Microsoft.Design", "CA1005:AvoidExcessiveParametersOnGenericTypes")]
public class MultiObject<T1, T2, T3> : MultiObject<T1, T2>
{
/// <summary>
/// Gets or sets the value of the third multi object component.
/// </summary>
/// <value>The third multi object component value.</value>
public T3 Third { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MultiObject{T1, T2, T3}"/> class.
/// </summary>
/// <param name="first">Multi object's first component value.</param>
/// <param name="second">Multi object's second component value.</param>
/// <param name="third">Multi object's third component value.</param>
public MultiObject(T1 first, T2 second, T3 third)
: base(first, second)
{
this.Third = third;
}
}
#endregion
任何當我必須傳遞多個列表時
#region MultiObject static helper class
/// <summary>
/// Provides static methods for creating multi objects with type inference.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi")]
public static class MultiList
{
/// <summary>
/// Creates a new <see cref="MultiObject{T1, T2}"/> object instance.
/// </summary>
/// <typeparam name="T1">The type of the first object.</typeparam>
/// <typeparam name="T2">The type of the second object.</typeparam>
/// <param name="first"><typeparamref name="T1"/> object instance.</param>
/// <param name="second"><typeparamref name="T2"/> object instance.</param>
/// <returns>
/// Returns a <see cref="MultiObject{T1, T2}"/> of <typeparamref name="T1"/> and <typeparamref name="T2"/> object instances.
/// </returns>
public static MultiList<T1, T2> New<T1, T2>(IList<T1> first, IList<T2> second)
{
return new MultiList<T1, T2>(first, second);
}
/// <summary>
/// Creates a new <see cref="MultiObject{T1, T2, T3}"/> object instance.
/// </summary>
/// <typeparam name="T1">The type of the first object.</typeparam>
/// <typeparam name="T2">The type of the second object.</typeparam>
/// <typeparam name="T3">The type of the third object.</typeparam>
/// <param name="first"><typeparamref name="T1"/> object instance.</param>
/// <param name="second"><typeparamref name="T2"/> object instance.</param>
/// <param name="third"><typeparamref name="T3"/> object instance.</param>
/// <returns>
/// Returns a <see cref="MultiObject{T1, T2, T3}"/> of <typeparamref name="T1"/>, <typeparamref name="T2"/> and <typeparamref name="T3"/> objects instances.
/// </returns>
public static MultiList<T1, T2, T3> New<T1, T2, T3>(IList<T1> first, IList<T2> second, IList<T3> third)
{
return new MultiList<T1, T2, T3>(first, second, third);
}
}
#endregion
#region MultiList<T1, T2>
/// <summary>
/// Represents a 2-multi object, or pair.
/// </summary>
/// <typeparam name="T1">The type of the multi object's first component.</typeparam>
/// <typeparam name="T2">The type of the multi object's second component.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi")]
public class MultiList<T1, T2> : MultiObject<IList<T1>, IList<T2>>
{
/// <summary>
/// Initializes a new instance of the <see cref="MultiList<T1, T2>"/> class.
/// </summary>
/// <param name="first">The first.</param>
/// <param name="second">The second.</param>
public MultiList(IList<T1> first, IList<T2> second) : base(first, second) { }
}
#endregion
#region MultiList<T1, T2, T3>
/// <summary>
/// Creates a new 3-multi object, or triple.
/// </summary>
/// <typeparam name="T1">The value of the first component of the multi object.</typeparam>
/// <typeparam name="T2">The value of the second component of the multi object.</typeparam>
/// <typeparam name="T3">The value of the third component of the multi object.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi")]
[SuppressMessage("Microsoft.Design", "CA1005:AvoidExcessiveParametersOnGenericTypes")]
public class MultiList<T1, T2, T3> : MultiObject<IList<T1>, IList<T2>, IList<T3>>
{
/// <summary>
/// Initializes a new instance of the <see cref="MultiList<T1, T2, T3>"/> class.
/// </summary>
/// <param name="first">The first.</param>
/// <param name="second">The second.</param>
/// <param name="third">The third.</param>
public MultiList(IList<T1> first, IList<T2> second, IList<T3> third) : base(first, second, third) { }
}
#endregion
但是在您要傳遞菜單的情況下,最好有一個基頁類,所有頁面都繼承自該頁面類,並且該頁面類提供所有常用屬性(菜單數據為一個)。
要在單個視圖中處理多個模型,我個人使用ViewBag。
請注意,如果您使用ViewBag,則會禁用從編譯器獲得的所有幫助,並且運行時錯誤/錯誤的發生可能性超過該屬性位於“普通”對象上並且編譯器會捕獲錯別字的情況。
這是使用動態對象的缺點,但是,還有許多其他優點。 在您的控制器中,您只需將數據/模型傳遞到ViewBag:
public ActionResult Index() {
ViewBag.TopMenu = TopMenu();
ViewBag.Student = Student();
return View();
}
然后在視圖中,將其調出:
@{
ViewBag.Title = "Index_ViewBag";
}
<h2>Index View Bag</h2>
<table>
<tr>
@foreach (var menu in ViewBag.TopMenu)
{
<td>
<a href="@menu.URL">@menu.Name</a>
</td>
}
</tr>
</table>
<p>
<ul>
@foreach (var student in ViewBag.Student)
{
<li>
<a href="@student.URL">@student.Name</a>
</li>
}
</ul>
</p>
還有另一種選擇,由一些MVC純粹主義者提出,但我發現它對我有用。 而不是在每個有“菜單”的頁面上包含兩個模型(我假設幾乎都是所有頁面),您可以在學生視圖中顯示您的菜單:
@Html.RenderAction("Menu");
這將調用它自己的動作,生成菜單視圖模型和“菜單”局部視圖。
對我來說,這是有道理的,但我知道很多人不喜歡它。
在.Net Framework 4.0中,您可以使用動態模型。
大致:
public class HomeController : Controller
{
public ActionResult Index()
{
dynamic viewmodel = new ExpandoObject();
viewmodel.Students = MyStudent();
viewmodel.MenuItems = MyMenuItems();
return View(mymodel);
}
}
如何訪問視圖代碼:
@model dynamic
@foreach (Student student in Model.Students)
}
<h1>@student.Name</h1>
}
@foreach (MenuItem menuItem in Model.MenuItems)
{
<h1>@menuItem.menuname</h1>
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.