我一直在研究MVC ViewModel,它包含我需要传递给View(而不是使用ViewBags)的标量数据值以及包含表格中的表格数据的IEnumerable。这是基于有人在早期的SO问题上提出的建议。这样,如果我将标量值作为常量添加到可能包含许多行的表中,我就不会有重复。
我正在粘贴我的(简化)数据模型并查看模型定义和相关的控制器操作。数据结构是我需要的,但是Visual Studio不会从这个Action创建一个View(右键单击并选择" Add Model with Model")。
我的问题是,给出了动作和模型定义,我需要做什么才能创建视图模型视图?
我认为自动脚手架是不可能的,因为ViewModel没有密钥,所以我期待手动编码。我不知道如何做到这一点,因为我所看到的所有示例都显示了ViewModel,它基本上相当于将两个表合并为一个更大的表。
我尝试过使用@model = [ViewModelName]和@model = IEnumerable,但都失败了。
二进制响应将是," Duh,错误正在告诉你究竟发生了什么。你没有钥匙。"但是这种反应并没有帮助我解决这个问题。如何使用此定义ViewModel并创建视图?
查看模型
public class StudentRosterViewModel
{
// This list is the "table" shown on the view
public IEnumerable<StudentRoster> StudentRosters { get; set; }
// These are scalar values apply to the view as a whole
public string SelectedCampus { get; set; }
public string SelectedFiscalYear { get; set; }
}
数据模型
[Table("StudentRoster")]
public partial class StudentRoster
{
public int ID { get; set; }
[Required]
[StringLength(3)]
public string Campus { get; set; }
[Required]
[StringLength(4)]
public string FiscalYear { get; set; }
[Required]
[StringLength(50)]
public string StudentName { get; set; }
public int StudentID { get; set; }
}
控制器操作:
public ActionResult FilterableIndex(string campus="MRA",string fiscalYear = "FY16")
{
StudentRosterViewModel vm = new StudentRosterViewModel();
// this is tabular data and goes in the "table"
vm.StudentRosters = db.StudentRosters
.Where(m => m.Campus == campus)
.Where(m => m.FiscalYear == fiscalYear)
.ToList();
// These are scalar values; they are not tabular
// These are needed to supply values to jQuery
vm.SelectedCampus = campus;
vm.SelectedFiscalYear = fiscalYear;
return View(vm);
}
答案 0 :(得分:1)
惯例是在Views文件夹中有一个与控制器名称对应的文件夹。例如,如果控制器为StudentRosterController
,则该文件夹将命名为StudentRoster
。
然后视图将对应于操作的名称 - FilterableIndex.cshtml
。
.cshtml文件将以
开头@model MvcApp.Controllers.StudentRosterViewModel
(其中MvcApp.Controllers是包含模型的命名空间。)
答案 1 :(得分:0)
感谢评论中的每个人(@StephenMuecke,@ LinTuan)和@ScottHannen的帮助,我能够创建ViewModel的工作和改进的View页面。
以下是我所做的结构改进。
[Key]
属性和Id属性 - 它实际上并不是它之前的工作原理。var headerMeta = Model.StudentRosters.FirstOrDefault();
,以便我可以在表正文部分使用@Html.DisplayNameFor
,我选择了另一个技巧(modelItem => item.[column name])
。headerMeta
变量。我称之为初步成功,因为我终于有数据到达视图。
@model ViewModelTest.Controllers.ViewModels.StudentRosterViewModel @{ ViewBag.Title = "FilterableIndex"; @*This enables us to read the StudentRoster column names*@ var headerMeta = Model.StudentRosters.FirstOrDefault(); } <h2>FilterableIndex</h2> <p>Test for reception of data</p> <ul> <li>Selected campus: @Model.SelectedCampus</li> <li>Selected fiscal year: @Model.SelectedFiscalYear</li> </ul> @*I'll add bootstrap styles later*@ <table> <tr> <th>@Html.DisplayNameFor(m => headerMeta.Campus)</th> <th>@Html.DisplayNameFor(m => headerMeta.FiscalYear)</th> <th>@Html.DisplayNameFor(m => headerMeta.StudentName)</th> <th>@Html.DisplayNameFor(m => headerMeta.StudentID)</th> </tr> @foreach (var item in Model.StudentRosters) { <tr> <td>@Html.DisplayFor(modelItem => item.Campus)</td> <td>@Html.DisplayFor(modelItem => item.FiscalYear)</td> <td>@Html.DisplayFor(modelItem => item.StudentName)</td> <td>@Html.DisplayFor(modelItem => item.StudentID)</td> </tr> }