Bram
Bram

Reputation: 739

How to update multiple rows at once from the View (ASP.NET - Core)

I've got a View which shows a table of Devices that are stored in my Database, the database is made using Code-First with Entity Framework Core. Now my goal is to update the EnableAlertsUpload boolean of multiple rows at the same time. As can be seen in the picture below.

enter image description here

Now when I run the code and press the update button the page will just refresh without updating the EnableAlertsUpload boolean. Any help on this would be greatly appreciated, most explanations only tell ho to update a single value by ID but not multiple rows at the same time.

My code looks as follows:

Controller

    public async Task<IActionResult> EditList()
    {
        var devices = db.Devices;

        return View(devices);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> EditList(int id, [Bind("EnableAlertsUpload")] Devices[] devices)
    {
        if (ModelState.IsValid)
        {
            try
            {
                foreach (Devices dev in devices)
                {
                    db.Update(dev);
                }
                await db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                return NotFound();
            }
            return RedirectToAction(nameof(IndexV2));
        }

        return View(devices);
    }

EditList View

@model IEnumerable<FrontlineAI.Models.Devices>

<h1>Devices</h1>

<form asp-action="EditList">
    <table class="table">
        <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.objid)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.device)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.group)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.host)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.EnableAlertsUpload)
            </th>
            <th></th>
        </tr>
        </thead>
        <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.objid)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.device)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.group)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.host)
                </td>
                <td>
                    <td>@Html.CheckBoxFor(modelItem => item.EnableAlertsUpload)</td>
                </td>
            </tr>
        }
        </tbody>
    </table>
    <button input type="submit" value="Edit">Update</button>
</form>

Devices Model

public partial class Devices
{
    [Key()]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int objid { get; set; }
    public string group { get; set; }
    public string device { get; set; }
    public string host { get; set; }
    public bool EnableAlertsUpload { get; set; }
}

Upvotes: 4

Views: 4253

Answers (1)

Yinqiu
Yinqiu

Reputation: 7190

It seems that you you did not successfully bind the data, you can try my following code.

EditList View

@model IEnumerable<Devices>

@{
    ViewData["Title"] = "Edit";
}

<h1>Devices</h1>

<form asp-action="EditList">
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.objid)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.device)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.group)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.host)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.EnableAlertsUpload)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @for (int i = 0; i < Model.Count(); i++)
                {
                <tr>
                    <td>
                        @Html.HiddenFor(m => m.ToList()[i].objid)
                        @Html.DisplayFor(m => m.ToList()[i].objid)
                    </td>
                    <td>
                        @Html.HiddenFor(m => m.ToList()[i].device)
                        @Html.DisplayFor(m => m.ToList()[i].device)
                    </td>
                    <td>
                        @Html.HiddenFor(m => m.ToList()[i].group)
                        @Html.DisplayFor(m => m.ToList()[i].group)
                    </td>
                    <td>
                        @Html.HiddenFor(m => m.ToList()[i].host)
                        @Html.DisplayFor(m => m.ToList()[i].host)
                    </td>
                    <td>@Html.CheckBoxFor(m => m.ToList()[i].EnableAlertsUpload)</td>
                </tr>
                }
        </tbody>
    </table>
    <button input type="submit" value="Edit">Update</button>
</form>

Controller

[HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> EditList(int id, List<Devices> devices)
    {
        if (ModelState.IsValid)
        {
            try
            {
                foreach (Devices dev in devices)
                {
                    _context.Update(dev);
                }
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                return NotFound();
            }
        }
       return RedirectToAction(nameof(EditList));
    }

Result enter image description here

Upvotes: 6

Related Questions