Performing HttpPost to store CheckBox Selected Val

2019-07-31 22:46发布

问题:

I have referred this question to learn how to post the checkbox selected values in the database.

However, I am not able to get my selected values on debug because of a NullReferenceException (see snapshots below) .

Here is my code:

Model:

 public class ProductModel
 {
    public string ProductId { get; set; }
    public string ProductName { get; set; }
    public bool Selected { get; set; }
    public string[] CheckedColumn { get; set; }
 }

View:

     @model IEnumerable<DemoApp.Models.ViewModels.ProductModel>

    @{
               ViewBag.Title = "CheckView";
     }

   <table> 
     <tr>
        <th>
          ProductId
        </th>
     <th>
        ProductName
     </th>
     <th>
        Selected
    </th>
        <th></th>
    </tr>

  @foreach (var item in Model) 
 {
   <tr>
      <td>
      @Html.DisplayFor(modelItem => item.ProductId)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.ProductName)
    </td>
    <td>
        @Html.CheckBoxFor(modelItem => item.Selected)
     </td>
   </tr> 
  }

  </table>
   @using (Html.BeginForm())  
   {
  <div>
  <input type="submit" name="AddResult" value="CheckView"/>
  </div>
    }

Controller:

    [HttpGet]
    public ActionResult CheckView()
    {
        DatabaseEntities db = new DatabaseEntities();

        var prodList = from b in db.SysUser3
                       select new ProductModel
                       {
                           ProductId = b.ProductId,
                           ProductName = b.ProductName,
                           Selected = b.SelectedProducts
                       };
        var p = prodList.ToList();
        return View(p);

    }

    [HttpPost]
    public ActionResult CheckView(FormCollection collection)
    {
        try
        {
            ProductModel model = new ProductModel();
            // Get all the selected checkboxlist, do db insertion
            model.CheckedColumn = collection["CheckView"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }

    }

Here are some of the snapshots I took while running the project

Am I doing something wrong in my View or Controller? can someone please help me ?

回答1:

Your model is null because you are not passing anything from Controller ACtion. Your CheckView ActionMethod should be an action that generates the view. Then your "CheckView" button should call another HttpPost action that would look like your previous CheckView. Let me know if it helps in the comments.

Action Result method that for the View:

    public ActionResult CheckView(ProductModel model)
    {
       return View("CheckView", model);
    }

Action for button click.

[HttpPost]
    public ActionResult TestView(FormCollection collection)
    {
        try
        {
            ProductModel model = new ProductModel();
            // Get all the selected checkboxlist, do db insertion
            model.CheckedColumn = collection["CheckView"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }

    }

And in View something like this:

@using (@Html.BeginForm("TestView", "Controller Name"))
{
//all your input here

// submit button here
}


回答2:

I agree with bobek. The problem is that you aren't reinitializing the model on the post action. Something like this:

[HttpGet]
    public ActionResult CheckView()
    {
        DatabaseEntities db = new DatabaseEntities();

        var prodList = from b in db.SysUser3
                       select new ProductModel
                       {
                           ProductId = b.ProductId,
                           ProductName = b.ProductName,
                           Selected = b.SelectedProducts
                       };
        var p = prodList.ToList();
        return View(p);

    }

    [HttpPost]
    public ActionResult CheckView(FormCollection collection)
    {
        try
        {
            ProductModel model = new ProductModel();
            // Get all the selected checkboxlist, do db insertion
            model.CheckedColumn = collection["CheckView"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            return RedirectToAction("Index");
        }
        catch
        {
            ModelState.addModelError("", "There was an issue processing the results.");
            DatabaseEntities db = new DatabaseEntities();

            var prodList = from b in db.SysUser3
                       select new ProductModel
                       {
                           ProductId = b.ProductId,
                           ProductName = b.ProductName,
                           Selected = b.SelectedProducts
                       };
            return View(prodList.ToList());
        }

    }

You would also probably want to refactor the select statement to avoid duplicate code. When you're dealing with lists, they don't maintain their state.



回答3:

This is a known bug. Attach a javascript function to your submit button that will iterate through the array of checkbox options and use .selected = true; on the ones which are checked. Only then will they be sent through the post.