Following code is to create users. I have a user class, I need to create users here. But I have department id's on a person and that department id refers to another table in the database whose name is Department.
public ActionResult Create()
{
// disable lazy because of error it creates
_db.Configuration.LazyLoadingEnabled = false;
var data = _db.Departments.OrderBy(a => a.DepartmentId).ToList();
ViewData["DepartmentList"] = data;
return View();
}
Here is View:
#{
var departmentLists = ViewData["DepartmentList"]; // Cast the list
}
<div class="form-group">
#Html.LabelFor(model => model.Department, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.Department, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Department, "", new { #class = "text-danger" })
</div>
</div>
This model.department part is the where i lost. I need to list my department in order of the list, when user select, i want to select the id of the department.
Like this;
So I want the user to see
Department Name + SubDepartment name
and when they choose from the list, the chosen thing is
departmentid
so I can add in the database like that.
Here is my Create Post method:
public ActionResult Create([Bind(Include = "ID,LastName,FirstMidName,EnrollmentDate,Email,Department,Position,Active")] User user)
{
if (ModelState.IsValid)
{
_db.Users.Add(user);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
Her is my User class;
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int DepartmentId { get; set; }
// Other fields removed for brevity
}
Here is Department class;
public class Department
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public string SubDepartmentName { get; set; }
}
Write your Create GET method as follows:
public ActionResult Create()
{
// disable lazy because of error it creates
_db.Configuration.LazyLoadingEnabled = false;
var departmentList = _db.Departments.Select(d => new
{
d.DepartmentId,
DepartmentName = d.DepartmentName + " " + d.SubDepartmentName
}).OrderBy(a => a.DepartmentId).ToList();
ViewBag.DepartmentList = new SelectList(departmentList,"DepartmentId","DepartmentName");
return View();
}
Then in the view:
<div class="form-group">
#Html.LabelFor(model => model.DepartmentId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("DepartmentId", ViewBag.DepartmentList as SelectList, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.DepartmentId, "", new { #class = "text-danger" })
</div>
</div>
Another problem is in your Create POST method. You are not allowing you DepartmentId to pass in your Bind include list. Please update you Create POST method as follows:
public ActionResult Create([Bind(Include = "ID,LastName,FirstMidName,EnrollmentDate,Email,DepartmentId,Position,Active")] User user)
{
if (ModelState.IsValid)
{
_db.Users.Add(user);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
Related
I'm creating a web app, and I can't seem to either create or edit entries with a foreign key. I'm creating a dropdown list to edit the records, and it's being populated correctly. But anytime I edit or create a new record with that foreign key I get "The value '2' is invalid."
My Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "chimeTimeID,ScheduleID,ChimeTimeStamp")] ChimeTime chimeTime)
{
ViewData["scheduleID"] = new SelectList(db.Schedules, "scheduleID", "ScheduleName", "Select a Schedule");
ViewBag.defaultModem = new SelectList(db.Schedules, "scheduleID", "ScheduleName", "Select a Schedule");
if (ModelState.IsValid)
{
db.Entry(chimeTime).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(chimeTime);
}
My View
<div class="form-group">
#Html.LabelFor(model => model.ScheduleID.ScheduleName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="dropdown">
#Html.DropDownListFor(model => model.ScheduleID, (SelectList)ViewBag.ScheduleName, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ScheduleID, "", new { #class = "text-danger" })
</div>
</div>
My Model
[Table("P_ChimeTime")]
public class ChimeTime
{
[Key]
public int chimeTimeID { get; set; }
public Schedule ScheduleID { get; set; }
[DataType(DataType.Time)]
[DisplayFormat(DataFormatString = "{0:T}", ApplyFormatInEditMode = true)]
public DateTime ChimeTimeStamp { get; set; }
}
So what am I doing wrong? It appears to me that MVC isn't parsing my result from the form to an int like it should.
So apparently this is how it should have been:
My Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "chimeTimeID,schedule,ChimeTimeStamp")] ChimeTime chimeTime)
{
ViewData["schedule"] = new SelectList(db.Schedules, "scheduleID", "ScheduleName", "Select a Schedule");
ViewBag.schedule = new SelectList(db.Schedules, "scheduleID", "ScheduleName", "Select a Schedule");
if (ModelState.IsValid)
{
chimeTime.ScheduleID = db.Schedules.Find (Int32.Parse (Request ["schedule"]));
db.ChimeTimes.Add(chimeTime);
db.SaveChanges();
return RedirectToAction("Index");
}
buildChimeJob(chimeTime);
return View(chimeTime);
}
My View:
<div class="form-group">
#Html.LabelFor(model => model.schedule, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="dropdown">
#Html.DropDownListFor(model => model.schedule, (SelectList)ViewBag.schedule, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.schedule, "", new { #class = "text-danger" })
</div>
</div>
My Model:
[Table("P_ChimeTime")]
public class ChimeTime
{
[Key]
public int chimeTimeID { get; set; }
public virtual Schedule ScheduleID { get; set; }
[DataType(DataType.Time)]
[DisplayFormat(DataFormatString = "{0:T}", ApplyFormatInEditMode = true)]
public DateTime ChimeTimeStamp { get; set; }
[ForiegnKey("ScheduleID")]
public int schedule {get; set;}
}
I am trying to define ViewModels that faithfully represent the view (to make strict use of that concept).
Some of the elements of the ViewModel are updated dynamically. The problem I have, is that when I do the Post, the ViewModel returns without the elements that were updated dynamically.
The update is done through jQuery, when an event is performed. An action is invoked through Url.Action, and a Div is updated.
I made an example to clarify the scenario. An application that only stores a location (state and city). For this I have three ViewModels: one to represent the States in a SelectList, one to represent the Cities in a SelectList, and finally one to represent the Location (formed by the two ViewModel that I mentioned first).
Models:
public class State
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
public class City
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int StateId { get; set; }
public virtual State State { get; set; }
}
ViewModels:
public class CitySelectListViewModel
{
public CitySelectListViewModel() { }
public CitySelectListViewModel(IEnumerable<Models.City> cities)
{
this.Cities = cities;
}
[Display(Name = "Cities")]
[Required]
public int? SelectedCityId { get; set; }
public IEnumerable<City> Cities { get; }
}
public class StateSelectListViewModel
{
public StateSelectListViewModel() { }
public StateSelectListViewModel(IEnumerable<State> states)
{
this.States = states;
}
[Display(Name = "States")]
[Required]
public int? SelectedStateId { get; set; }
public IEnumerable<State> States { get; }
}
public class LocationCreateViewModel
{
public LocationCreateViewModel() { }
public LocationCreateViewModel(ICollection<State> states)
{
this.StateSelectListViewModels = new StateSelectListViewModel(states);
this.CitySelectListViewModel = new CitySelectListViewModel();
}
public StateSelectListViewModel StateSelectListViewModels { set; get; }
public CitySelectListViewModel CitySelectListViewModel { set; get; }
}
Location [Controller]:
public class LocationController : Controller
{
private DALDbContext db = new DALDbContext();
// GET: Location/Create
public ActionResult Create()
{
LocationCreateViewModel locationCreateViewModel = new LocationCreateViewModel(db.States.ToList());
return View(locationCreateViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(LocationCreateViewModel pLocationCreateViewModel)
{
if (ModelState.IsValid)
{
//db.States.Add(state);
//db.SaveChanges();
return RedirectToAction("Index", "Home");
}
LocationCreateViewModel locationCreateViewModel = new LocationCreateViewModel(db.States.ToList());
return View(locationCreateViewModel);
}
public ActionResult CitySelectList(int? stateId)
{
CitySelectListViewModel citySelectListViewModel = new CitySelectListViewModel(db.Cities.Where(c => c.StateId == stateId).ToList());
return View(citySelectListViewModel);
}
}
Create [View]:
#model ViewModelExample.ViewModels.LocationCreateViewModel
....
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>State</h4>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.StateSelectListViewModels.SelectedStateId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.StateSelectListViewModels.SelectedStateId, new SelectList(Model.StateSelectListViewModels.States, "Id", "Name"), "Select a State", htmlAttributes: new { #class = "form-control", #id = "StateSelectList" })
#Html.ValidationMessageFor(model => model.StateSelectListViewModels.SelectedStateId, "", new { #class = "text-danger" })
</div>
</div>
<div id="CityContainer">
#Html.Action("CitySelectList")
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
// Fill City DropDownList
$('#StateSelectList').change(function () {
var selectedStateId = this.value;
$('#CityContainer').load('#Url.Action("CitySelectList")?stateId=' + selectedStateId);
});
});
</script>
}
CitySelectList [View]:
#model ViewModelExample.ViewModels.CitySelectListViewModel
....
<div class="form-group">
#Html.LabelFor(model => model.SelectedCityId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedCityId, new SelectList(Model.Cities, "Id", "Name"), "Select a City", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.SelectedCityId, "", new { #class = "text-danger" })
</div>
</div>
I will show the execution of my example, and I will show the problem through the inspection of the ViewModel that I receive after the Post:
I select a State and a City, and I press Create.
I inspect the ViewModel received after the Post. We can see how CitySelectListViewModel is null, and what I want is to bring the last ViewModel that was updated through jQuery.
I admit that I have provided a long example, but it is the only way I found to explain what I need. Thanks in advance.
VS-Project of the example
I'ts because you are preventing the modelBinder to accurately bind to LocationCreateViewModel in your Create action when replacing the inner HTML of <div id="CityContainer"> (thats what you do with $('#CityContainer').load(...). You instruct the model binder to bind to
#model ViewModelExample.ViewModels.CitySelectListViewModel and as a result you get this HTML for the city select list:
One way of solving this is modifying CitySelectList.cshtml to:
#model ViewModelExample.ViewModels.LocationCreateViewModel
#{
Layout = null;
}
<div class="form-group">
#Html.LabelFor(model => model.CitySelectListViewModel.SelectedCityId,
htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model =>
model.CitySelectListViewModel.SelectedCityId, new
SelectList(Model.CitySelectListViewModel.Cities, "Id", "Name"), "Select a City", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CitySelectListViewModel.SelectedCityId, "", new { #class = "text-danger" })
</div>
</div>
and your CitySelectList action to:
public ActionResult CitySelectList(int? stateId)
{
LocationCreateViewModel locationCreateViewModel = new LocationCreateViewModel();
locationCreateViewModel.CitySelectListViewModel = new CitySelectListViewModel(db.Cities.Where(c => c.StateId == stateId).ToList());
return View(locationCreateViewModel);
}
But I would recommend custom model binding as well.
Hi I have the following model:
public class ActiveProducts
{
public int ID { get; set; }
public virtual Product Product { get; set; }
}
and for data context I have:
public DbSet<ActiveProduct> ActiveProducts { get; set; }
I wanted to create a controller and views to do the CRUD operations
How would I be able to generate a view for the create and edit so that I have a drop down list of products?
I used the standard method of creating a controller using the model, with the CRUD operations and it didn't render out anything for the create.
Okay, since Product_ID holds the primary key value of the Products table, then this should work in your controller:
public ActionResult Create()
{
ViewBag.Product_ID = new SelectList(db.Product, "ID", "Product");
}
[HttpPost]
public ActionResult Create([Bind(Include = "ID, Product_ID" /*etc*/)] ActiveProducts activeProducts)
{
ViewBag.Product_ID = new SelectList(db.Product, "ID", "Product", activeProducts.Product_ID);
}
then in your Create View:
<div class="form-group">
#Html.LabelFor(model => model.Product_ID, "Product:", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("Product_ID", null, "-- Select Product --", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Product_ID, "", new { #class = "text-danger" })
</div>
</div>
I have two classes where one is a parent class for the other. The basic CRUD functions was created in the controller. In the design of my table I have the parent id in my child class as the foreign key. In the view for Create function of the child, I am asked to enter the parent ID. I have changed the Create to accept the ID of the parent. But when I remove the code for selecting the parent id in the view I get exception in my Create. Is there a way I can set the parent ID in both my create functions(Over loaded functions).
public ActionResult Create(int? id)
{
ViewBag.LsystemID = new SelectList(db.Lsystem, "LsystemID", "LsystemName",id);
ViewBag.TCID = new SelectList(db.TC, "TCID", "TCName");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "OptionID,OptionName,TCID,LsystemID")] Option option)
{
if (ModelState.IsValid)
{
db.Option.Add(option);
db.SaveChanges();
return RedirectToAction("Index");
}
// ViewBag.LsystemID = new SelectList(db.Lsystem, "LsystemID", "LsystemName", op);
ViewBag.TCID = new SelectList(db.TC, "TCID", "TCName", option.TCID);
return View(option);
}
View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.LabelFor(model => model.OptionName, htmlAttributes: new { #class = "control-label col-md-2" })
#Html.EditorFor(model => model.OptionName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.OptionName, "", new { #class = "text-danger" })
#Html.LabelFor(model => model.TCID, "TCID", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownList("TCID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.TCID, "", new { #class = "text-danger" })
#Html.LabelFor(model => model.LsystemID, "LsystemID", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownList("LsystemID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.LsystemID, "", new { #class = "text-danger" })
<input type="submit" value="Create" class="btn btn-default" />
}
How can I pass the value LsystemID without being shown in the View?
EDIT 1 : Adding Model class
public class Lsystem
{
public int LsystemID { get; set; }
public string LsystemName { get; set; }
public virtual ICollection<Option> Options { get; set; }
// public int OptionId { get; set; }
}
public class Option
{
public int OptionID { get; set; }
public string OptionName { get; set; }
public int TCID { get; set; }
public virtual TC tc { get; set; }
public virtual Lsystem Lsystem { get; set; }
public int LsystemID { get; set; }
public virtual ICollection<OptionValue> OptionValues { get; set; }
}
Start by creating a view model representing what you need in the view (add validation and display attributes as required
public class OptionVM
{
public int Lsystem { get; set; }
public string Name { get; set; }
public int TC { get; set; }
public SelectList TCList { get; set; }
}
and in the controller
public ActionResult Create(int? id)
{
OptionVM model = new OptionVM
{
Lsystem = id // set the parent
};
ConfigureViewModel(model);
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(OptionVM model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
Option option = new Option
{
OptionName = model.Name,
TCID = model.TC,
LsystemID= model.Lsystem
};
db.Option.Add(option);
db.SaveChanges();
return RedirectToAction("Index");
}
private void ConfigureViewModel(OptionVM model)
{
model.TCList = new SelectList(db.TC, "TCID", "TCName");
}
and in the view
#model OptionVM
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Lsystem)
#Html.LabelFor(m => m.Name)
#Html.TextBoxFor(m => m.Name)
#Html.ValidationMesageFor(m => m.Name)
#Html.LabelFor(m => m.TC)
#Html.DropDownListFor(m => m.TC, Model.TCList, "Please select")
#Html.ValidationMesageFor(m => m.TC)
<input type="submit" ... />
}
I am currently working on a project to model a bikestore. In my 'Order' object, I have a lis object for the Bike items on the order. How would I add bikes to this list? I.E I want to display a list of availiable bikes in the Create view, an add one or more of them to the order.
My Controller:
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "OrderNumber,CustomerName,OrderDate,PickupDate,TotalCost,PaymentMethod")] Order order)
{
if (ModelState.IsValid)
{
db.Orders.Add(order);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(order);
}
My Inventory model
public class Inventory
{
public int Id { get; set; }
public string SerialNumber { get; set; }
public virtual Store Store { get; set; }
public int? StoreId { get; set; }
public string Model { get; set; }
public string Description { get; set; }
public Decimal InventoryCost { get; set; }
public Decimal RecSalePrice { get; set; }
public Decimal SalePrice { get; set; }
public string PaymentMethod { get; set; }
public virtual BikeCategory Category { get; set; }
public int? CategoryId { get; set; }
}
My Order model:
namespace BikeStore.Models
{
public class Order
{
public Order()
{
OrderedItems = new List<Inventory>();
}
public string CustomerName { get; set; } //FROM CONTROLLER User.Identity.Name
public virtual List<Inventory> OrderedItems { get; set; }
[Key, DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int OrderNumber { get; set; }
In the create view for orders:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Order</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.CustomerName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CustomerName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CustomerName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.OrderDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OrderDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.OrderDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PickupDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PickupDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PickupDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.TotalCost, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TotalCost, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TotalCost, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PaymentMethod, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PaymentMethod, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PaymentMethod, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Start by creating view models to represent what you want to display/edit in the view (add display and validation attributes as appropriate)
public class InventoryVM
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
public class OrderVM
{
public string PaymentMethod { get; set; }
public List<InventoryVM> Inventory { get; set; }
}
Note that CustomerName, OrderDate and Total are not appropriate (you don't want a user editing these - they should be set in the POST method immediately before saving the order). Not sure what PickupDate represents but if its the actual date then that's not appropriate either (it would be set separately when the order is collected). I would also suggest that PaymentMethod be an enum or collection of PaymentType's and that you and use a dropdownlist in the view for selection.
Then the GET method would be
public ActionResult Create()
{
// Get all available bikes, for example
var inventory = db.Inventory;
OrderVM model = new OrderVM
{
Inventory = inventory.Select(i => new
{
ID = i.ID,
Name = i.Model // modify this to suit what you want to display in the view
}).ToList()
};
return View(model);
}
And in the view
#model yourAssembly.OrderVM
#using (Html.BeginForm())
{
for(int i = 0; i < Model.Inventory.Count; i++)
{
#Html.HiddenFor(m => m.Inventory[i].ID)
#Html.CheckBoxFor(m => m.Inventory[i].IsSelected)
#Html.LabelFor(m => m.Inventory[i].IsSelected, Model.Inventory[i].Name)
}
#Html.TextBoxFor(m => m.PayentMethod)
<input type="submit" value="Create" />
}
And the POST method would be
public ActionResult Create(OrderVM model)
{
// Initialize a new Order and map properties from view model
var order = new Order
{
CustomerName = User.Identity.Name,
OrderDate = DateTime.Now,
....
PaymentMethod = model.PaymentMethod
}
// Save the order so that you now have its `ID`
IEnumerable<int> selectedItems = model.Inventory.Where(i => i.IsSelected).Select(i => i.ID);
foreach(var item in selectedItems)
{
// You have not shown the model for this so just guessing
var orderItem = new OrderItem{ OrderID = order.Id, InventoryId = item };
db.OrderItems.Add(orderItem);
}
db.SaveChanges();
}
Side notes:
If you want to be able to allow users to select more that one of any
item, the you could change bool IsSelected to say int Quantity
If you you want to display additional information about the items,
say Description and Cost you can include additional properties
in the InventoryVM view model and display them with
#Html.DisplayFor(m => m.Inventory[i].Description)
If you want to display a total cost for all selected items in the
view, you will need to use javascript/jquery
If ModelState could be invalid, you will need to repopulate the
properties of InventoryVM before you return the view (as shown
only the ID and IsSelected properties post back) or include
hidden inputs for the other properties in the view