【问题标题】:How to create VIew of ViewModel, where ViewModel is an IEnumerable with two strings?如何创建 ViewModel 的视图,其中 ViewModel 是带有两个字符串的 IEnumerable?
【发布时间】:2016-05-12 02:28:10
【问题描述】:

我一直在研究一个 MVC ViewModel,它包含我需要传递给 View(而不是使用 ViewBags)的标量数据值,以及一个包含表中表格数据的 IEnumerable。这是基于某人对较早的 SO 问题提出的建议。这样,如果我将标量值作为常量添加到可能有很多行的表中,就不会出现重复。

我正在粘贴我的(简化的)数据模型和视图模型定义以及有问题的控制器操作。数据结构是我需要的,但 Visual Studio 不会从此操作创建视图(右键单击并选择“使用模型添加视图”)。

我的问题是,给出了动作和模型定义,我需要做什么才能创建视图模型的视图?

我认为自动脚手架是不可能的,因为 ViewModel 没有键,所以我期待手动编码。我不知道该怎么做,因为我看到的所有示例都显示 ViewModel 本质上相当于将两个表合并为一个更大的表。

我尝试过使用@model = [ViewModelName] 和@model = IEnumerable,但都失败了。

二进制响应是,“呃,错误告诉你到底发生了什么。你没有钥匙。”但这种反应并不能帮助我解决这个问题。我该如何继续这个 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);
}

【问题讨论】:

  • 操作你的“FilterableIndex”,它是 HttpPost 或 Get,使用 json 或来自的请求
  • 您将StudentRosterViewModel 的实例传递给视图,因此视图需要@model StudentRosterViewModel,然后生成您的表@foreach(var item in Model.StudentRosters) { ....
  • 请注意,它必须是 return View(vm); 才能将模型返回到视图。
  • @StephenMuecke -- 你在另一个迭代中抓住了我,我之前有 View(vm) 在那里......
  • @Rubix_Revenge 我认为您的错误是您没有为 tableModel 设置密钥,您需要在属性 public int ID { get; 上添加属性“[Key]”放; }

标签: c# asp.net asp.net-mvc asp.net-mvc-viewmodel


【解决方案1】:

约定是在您的 Views 文件夹中有一个与您的控制器名称相对应的文件夹。例如,如果控制器是StudentRosterController,则文件夹将命名为StudentRoster

然后视图将对应于操作的名称 - FilterableIndex.cshtml

.cshtml 文件将以

开头
@model MvcApp.Controllers.StudentRosterViewModel

(其中 MvcApp.Controllers 是包含您的模型的命名空间。)

【讨论】:

  • 谢谢。这也很有帮助。正如您发布的那样,我终于达到了尤里卡时刻——这是答案的一部分。我将在大约一个小时后发布我的答案。
【解决方案2】:

感谢 cmets (@StephenMuecke、@LinhTuan) 和 @ScottHannen 中的每个人的帮助,我能够创建 ViewModel 的工作和改进的视图页面。

这是我所做的结构改进。

  1. 我创建了一个 ViewModels 文件夹并将 ViewModel 类放在那里(不再位于 Models 文件夹中)。
  2. 我从 ViewModel 中取出了 [Key] 属性和 Id 属性——这确实不是让它看起来工作的原因。
  3. 我右键单击操作名称并选择“创建视图”(没有模型为空)
  4. 视图已成功创建。您在下面看到的 View 代码是访问 ViewModel 属性和显示数据的能力的基本测试——我可以添加 Bootstrap 样式和功能,现在我有一个基本测试。
  5. IEnumerable 需要做一些工作才能解压。后来我学会了如何添加一个变量var headerMeta = Model.StudentRosters.FirstOrDefault();,这样我就可以在表格正文部分使用@Html.DisplayNameFor,我又学会了一个技巧(modelItem =&gt; item.[column name])
  6. 可能的进一步步骤是创建自定义 DisplayFor 和 DisplayNameFor 帮助程序,以便我可以更直接地使用 Html 帮助程序,而无需添加 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>
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多