Here is my situation:
I have a controller action called OrderFromCategory which fills a view model with data (view model in this case is just a list of items of type of another view model). This gets passed to the strongly typed view which displays the list of items and lets user change quantity of each item. On Post, my post controller action receives the model object back, but with no objects in the list. Am I miss-wiring something? At a loss, any help would be appreciated! Thanks much in advance!
Also, is my validation wired up correctly? Can't test that until I get the model data to be persistent!
Here is the code:
ViewModel:
public class MenuItemsModel
{
public MenuItemsOrderModel()
{
items = new List<MenuItemOrderModel>();
}
public List<MenuItemOrderModel> items { get; set; }
}
public class MenuItemOrderModel
{
public int ItemID { get; set; }
[Display(Name = "Name")]
public string ItemName { get; set; }
[Display(Name = "Description")]
public string Description { get; set; }
[Display(Name = "Price")]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
[Display(Name = "Quantity")]
public int Quantity { get; set; }
public string Qualifier { get; set; }
public int Minimum { get; set; }
}
Controllers:
public ActionResult OrderFromCategory(string id)
{
ViewData["category"] = id;
Models.MenuItemsModel model = new Models.MenuItemsModel();
foreach (Models.MenuItem item in Models.MenuItemRepository.GetMenuItemsForCategory(id))
{
model.items.Add(new Models.MenuItemOrderModel()
{
ItemID = item.ItemID,
Description = item.Description,
ItemName = item.Name,
Price = item.Price,
Qualifier = item.PriceQualifier,
Minimum = item.MinimumQuantity,
Quantity = ((namespace.Models.Order)Session["order"]).GetItemQuantity(item.ItemID)
});
}
return View(model);
}
[HttpPost]
public ActionResult OrderFromCategory(string id, Models.MenuItemsModel model)
{
//check for user inputs in all items
foreach (string inputKey in Request.Form.AllKeys)
{
Models.MenuItem item = Models.MenuItemService.GetMenuItem(int.Parse(inputKey));
int minimum = item.MinimumQuantity;
int quantity = string.IsNullOrEmpty(Request.Form[inputKey]) ? 0 : int.Parse(Request.Form[inputKey]);
if(quantity != 0 && quantity < minimum)
{
ModelState.AddModelError(string.Format("Quantity", item.ItemID), string.Format("Minimum of {0} required for order", minimum));
}
if (!ModelState.IsValid)
{
return View(model);
}
Models.OrderService.UpdateItemInOrder((Models.Order)Session["order"], item.ItemID, quantity);
}
return RedirectToAction("PlaceOrder");
}
View:
@model namespace.Models.MenuItemsModel
@{
ViewBag.Title = "Order from " + ViewData["category"];
}
<h2>Order from @ViewData["category"] </h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true, "Order was unsuccessful. Please correct the errors and try again.")
<div>
<fieldset>
@foreach (namespace.Models.MenuItemOrderModel item in Model.items)
{
<div class="item_group">
<div class = "item_name">
@item.ItemName
</div>
<div class = "item_description">
@item.Description
</div>
<div class = "item_price">
[email protected] /@item.Qualifier (@item.Minimum miminum)
</div>
<div class = "item_quantity">
<div class="editor-label">
Quantity
</div>
<div class="editor-field">
@Html.TextBox(item.ItemID.ToString(), item.Quantity.ToString(), new { @class = "quantity_textbox", @type = "number"})
@Html.ValidationMessage("Quantity", "*")
</div>
</div>
</div>
}
<p>
<input type="submit" value="Continue" />
</p>
</fieldset>
</div>
}