I have been working on an MVC ViewModel that contains scalar data values I need to pass to the View (instead of using ViewBags) along with an IEnumerable that contains the tabular data that goes in the table. This was based on a suggestion someone made on an earlier SO question. This way, there is no duplication I would have if I added the scalar values as constants to a table that could have many, many rows.
I am pasting my (simplified) data model and view model definitions and the controller action in question. The data structures are what I need it to be, but Visual Studio won't create a View from this Action (right-click and select "Add View with Model").
My question, is given the Action and Model definitions, what do I need to do so that I can create a View of the View Model?
I'm figuring auto-scaffold is out of the question because the ViewModel has no key, so I'm expecting manual coding. I have no idea how to do this, because all the examples I've seen show ViewModels that are essentially the equivalent of merging two tables into a larger table.
I have tried using @model = [ViewModelName] and @model = IEnumerable, but both failed.
The binary response would be, "Duh, the error is telling you exactly what's going on. You don't have a Key." But that response doesn't help me resolve this. How do I move forward with this definition of the ViewModel and create a View?
View Model
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; }
}
Data Model
[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; }
}
Controller Action:
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);
}
The convention is that in your Views folder there's a folder corresponding to the name of your controller. For example, if the controller is StudentRosterController
then the folder would be named StudentRoster
.
Then the view would correspond to the name of the action - FilterableIndex.cshtml
.
The .cshtml file would begin with
@model MvcApp.Controllers.StudentRosterViewModel
(Where MvcApp.Controllers is the namespace that contains your model.)