lundi 22 janvier 2018

mvc form check box stays empty after being checked

I'm building an e-commerce site in ASP.NET MVC in C#. I recently added a new boolean property 'IsDailySpecial' to my Item entity and am using HTML, HTML helper methods, and RazorSyntax to render the property state in a checkbox. Because the Item class is dependent on other classes for data, I created an ItemModel that I pass to the necessary views. All of this is in the Admin area of my app. I have Index, Create, Edit, Delete, and Details views that function properly...i.e. I can use them on Items as you would expect and all the data saves to the database. I can tick the 'IsDailySpecial' check box in the Create/Edit views, save the Item and/or changes, and see it in the Index view. But the check box is always empty in the Index, Edit, and Details views even though its data is being saved correctly. Just FYI, the other boolean property 'InStock' (which also uses a checkbox) has no problems.

Relevant parts of the ItemController.cs

public class ItemController : Controller
{
    private ApplicationDbContext db = new ApplicationDbContext();

    // GET: Admin/Item
    public async Task<ActionResult> Index()
    {
        var items = await db.Items.ToListAsync();
        var model = await items.Convert(db);
        model = model.OrderBy(c => c.Manufacturer);
        return View(model);
    }


    // GET: Admin/Item/Details/5
    public async Task<ActionResult> Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Item item = await db.Items.FindAsync(id);
        if (item == null)
        {
            return HttpNotFound();
        }

        var itemModel = await item.Convert(db);
        return View(itemModel);
    }

    // POST: Admin/Item/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Create([Bind(Include = "Id,ManufacturerId,ModelNumber,SKU,UPCCode,ShortDescription,LongDescription,ImageURL,CategoryId,ListPrice,SalePrice,Quantity,InStock,IsDailySpecial")] Item item)
    {
        if (ModelState.IsValid)
        {
            db.Items.Add(item);
            await db.SaveChangesAsync();
            return RedirectToAction("Index");
        }
        return View(item);
    }

    // GET: Admin/Item/Edit/5
    public async Task<ActionResult> Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Item item = await db.Items.FindAsync(id);
        if (item == null)
        {
            return HttpNotFound();
        }

        var items = new List<Item>();
        items.Add(item);
        var itemModel = await items.Convert(db);
        return View(itemModel.FirstOrDefault());
    }

    // POST: Admin/Item/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Edit([Bind(Include = "Id,ManufacturerId,ModelNumber,SKU,UPCCode,ShortDescription,LongDescription,ImageURL,CategoryId,ListPrice,SalePrice,Quantity,InStock,IsDailySpecial")] Item item)
    {
        if (ModelState.IsValid)
        {
            db.Entry(item).State = EntityState.Modified;
            await db.SaveChangesAsync();
            return RedirectToAction("Index");
        }
        return View(item);
    }

Relevant parts of Item.cs

public class Item
{
    [DisplayName("In Stock")]
    public bool InStock { get; set; }

    [Required]
    public int Quantity { get; set; }

    [DisplayName("Daily Special")]
    public bool IsDailySpecial { get; set; }
}

Relevant parts of ItemModel.cs

public class ItemModel
{
    [DisplayName("In Stock")]
    public bool InStock { get; set; }

    [Required]
    public int Quantity { get; set; }

    [DisplayName("Daily Special")]
    public bool IsDailySpecial { get; set; }

Relevant parts of Index.cshtml

@model IEnumerable<OnlineRetailer.Areas.Admin.Models.ItemModel>
@using OnlineRetailer.Areas.Admin.Models;

<div class="admin-view-container">
    <h3>Items</h3>
    <table class="table table-condensed table-striped">
        <tr class="success">
            <th>
                @Html.DisplayNameFor(model => model.Quantity)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.InStock)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.IsDailySpecial)
            </th>
            <th></th>
        </tr>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Quantity)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.InStock)
                </td>
                <td>
                    @Html.DisplayFor(modelItem =>   item.IsDailySpecial)
                </td>
            </tr>
        }
    </table>
</div>

Relevant parts of create and edit views

@model OnlineRetailer.Areas.Admin.Models.ItemModel
@using OnlineRetailer.Extensions

<div class="admin-view-container">
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()

        <div class="form-horizontal">
            <h3>Create Item</h3>
            <hr />
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })

            <div class="form-group">
                @Html.LabelFor(model => model.Quantity, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Quantity, "", new { @class = "text-danger" })
                </div>
            </div>


            <div class="form-group">
                @Html.LabelFor(model => model.InStock, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    <div class="checkbox">
                        @Html.EditorFor(model => model.InStock)
                        @Html.ValidationMessageFor(model => model.InStock, "", new { @class = "text-danger" })
                    </div>
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.IsDailySpecial, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    <div class="checkbox">
                        @Html.EditorFor(model => model.IsDailySpecial)
                        @Html.ValidationMessageFor(model => model.IsDailySpecial, "", new { @class = "text-danger" })
                    </div>
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-success" />
                </div>
            </div>
        </div>
    }
</div>

I've searched SO, GitHub, CodeProject, TutorialsTeacher, MS Documentation, etc...and haven't found a reason as to why this is happening.

Any thoughts as to why this is happening would be greatly appreciated!




Aucun commentaire:

Enregistrer un commentaire