0
votes

In the code below I have created an index view that enables users to check records that they want to update. When clicking on the submit button, they are supposed to be redirected to a webpage, and some code needs to be executed to update these records.

The following is the code that I have implemented:

The view:

@model IEnumerable<BulkDelete.Models.Employee>

@{int[] employeesToUpdate;}
    <div style="font-family:Arial">
        @using (Html.BeginForm("UpdateMultiple", "Home", FormMethod.Post))
        {
            <table class="table">
                <thead>
                    <tr>
                        <td>Checkbox<br /></td>

                        <th>Name</th>
                        <th>Gender</th>
                        <th>Email</th>
                    </tr>
                </thead>
                <tbody>

                    @foreach (var item in Model)
                    {
                        <tr>
                            <td>
                                <input type="checkbox" name="employeesToUpdate" id="employeesToUpdate" value="@item.ID" />
                            </td>
                            <td>@item.Name</td>
                            <td>@item.Gender</td>
                            <td>@item.Email</td>
                        </tr>
                    }
                </tbody>
            </table>

            <input type="submit"  value="update selected employees" />
        }
    </div>

The controller:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BulkDelete.Models;

namespace BulkDelete.Controllers
{
    public class HomeController : Controller
    {
        SampleDBContext db = new SampleDBContext();
        public  System.Web.SessionState.HttpSessionState Session { get; }

        public ActionResult Index()
        {
            return View(db.Employees.ToList()) ;
        }

        [HttpPost]
        public ActionResult UpdateMultiple(IEnumerable<int> employeesToUpdate)
        {
            return RedirectToAction("UpdateMultipleRecords");
        }
        
        //[HttpPost]
        public ActionResult UpdateMultipleRecords()
        {
            IEnumerable<int> employeesToUpdate = (IEnumerable<int>)TempData["employeesToUpdate"];
            var listemployee = db.Employees.Where(x => employeesToUpdate.Contains(x.ID));

            foreach (var item in listemployee)
            {
                int itemid = item.ID;

                Employee e = db.Employees.Find(itemid);
                e.Email = "hello.";
                // e = db.Employees.Find(item);
                db.Entry(e).State = EntityState.Modified;
            }

            db.SaveChanges();

            return RedirectToAction("Index");
        }
    }
}

I am getting the same error over and over:

Unable to create a null constant value of type 'System.Collections.Generic.IEnumerable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.

Only entity types, enumeration types or primitive types are supported in this context.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NotSupportedException: Unable to create a null constant value of type 'System.Collections.Generic.IEnumerable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. Only entity types, enumeration types or primitive types are supported in this context.

1

1 Answers

0
votes

Your form post method expects this signature, you also seem to be depending on TempData in the RedirectToAction, so you need to set the TempData in your post method:

    [HttpPost]
    public ActionResult UpdateMultiple(IEnumerable<int> employeesToUpdate)
    {
        //Set the TempData
        TempData["employeesToUpdate"] = employeesToUpdate;
        return RedirectToAction("UpdateMultipleRecords");
    }

In your view, you need to modify the name attribute on your checkbox elements like so, since it is an IEnumerable the name needs to be indexed, also, currently you are using the same id on all your checkboxes, id should be unique to each element, so you can use the iter variable to append to the id of the checkboxes:

@{int[] employeesToUpdate;} @*This doesn't look like it's necessary*@
@{int iter = 0;} @*Declare an iterator variable*@

.......

@for (var item in Model)
 {
    <tr>
        <td>
           @*index the controller parameter's IEnumerable*@
           <input type="checkbox" name="employeesToUpdate[@iter]" id="employeesToUpdate_@iter" value="@item.ID" /> 
        </td>
        <td>@item.Name</td>
        <td>@item.Gender</td>
        <td>@item.Email</td>
   </tr>
   iter++;
 }