如何创建ViewModel的VIew,其中ViewModel是一个带有两个字符串的IEnumerable?

时间:2016-05-12 02:28:11

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

我一直在研究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);
}

2 个答案:

答案 0 :(得分:1)

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

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

.cshtml文件将以

开头
@model MvcApp.Controllers.StudentRosterViewModel

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

答案 1 :(得分:0)

感谢评论中的每个人(@StephenMuecke,@ LinTuan)和@ScottHannen的帮助,我能够创建ViewModel的工作和改进的View页面。

以下是我所做的结构改进。

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

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

相关问题