简体   繁体   中英

ASP.NET MVC3 View model is not null but missing data when posted back to Controller

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">
                $@item.Price /@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>
}

You don't seem to have corresponding input fields in your form for the fields of your view model. Also your the naming of your quantity textbox is wrong. Try replacing your foreach loop in the view with the following:

@for (int i = 0; i < Model.items.Count; i++)
{
    @Html.HiddenFor(x => x.items[i].ItemID)
    @Html.HiddenFor(x => x.items[i].ItemName)
    @Html.HiddenFor(x => x.items[i].Description)
    @Html.HiddenFor(x => x.items[i].Price)
    @Html.HiddenFor(x => x.items[i].Qualifier)
    @Html.HiddenFor(x => x.items[i].Minimum)

    <div class="item_group">
        <div class = "item_name">
            @Model.items[i].ItemName
        </div>
        <div class = "item_description">
            @Model.items[i].Description
        </div>
        <div class = "item_price">
            $@Model.items[i].Price /@Model.items[i].Qualifier  (@Model.items[i].Minimum miminum)
        </div> 
        <div class = "item_quantity">
        <div class="editor-label">
            Quantity
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(x => x.items[i].Quantity, new { @class = "quantity_textbox", @type = "number" })
            @Html.ValidationMessageFor(x => x.items[i].Quantity, "*")
        </div>
        </div>
    </div>
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM