skip to Main Content

i’m making a webbapplication with ASP.NET MVC and im trying to edit my list of objects. If i for example add a product to the site and then click on edit for that product to change the prize i just get a new object with the new prize instead of changing the prize to the product.

So the problem is that instead of updating the products it just adds a new one.

this is how my controller for the products looks like:

using auktioner_MarcusR91.Data;
using auktioner_MarcusR91.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace auktioner_MarcusR91.Controllers
{
    public class InventoryController : Controller
    {
        private readonly AppDbContext _db;

        public InventoryController(AppDbContext db)
        {
            _db = db;
        }
        public IActionResult Index()
        {
            IEnumerable<Inventory> objInventoryList = _db.Inventories;
            return View(objInventoryList);
        }

        //GET
        public IActionResult Create()
        {
            return View();
        }
        //Post
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(Inventory inventory)
        {
            _db.Inventories.Add(inventory);
            _db.SaveChanges();
            return RedirectToAction("index");
        }

        //GET
        public IActionResult Edit(int? id)
        {
            if (id == 0 || id == 5) 
            {
                return NotFound();
            }
            var inventoryFromDb = _db.Inventories.Find(id);

            if (inventoryFromDb == null)
            {
                return NotFound();
            }
            return View(inventoryFromDb);
        }
        //Post
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Edit(Inventory inventory)
        {
            if (ModelState.IsValid) 
            {
                _db.Inventories.Update(inventory);
                _db.SaveChanges();
                return RedirectToAction("index");
            }
            return View(inventory);
            
        }
    }
}

I think there is something wrong in my controller.

However here is also my view for when i edit a product:

@model Inventory

<form method = "post" asp-action = "Edit">
    <div class = "border p-3 mt-4">
        <div class = "row pb-2">
            <h2 class = "text-primary">Edit Inventory</h2>
            <hr />
        </div>
        <div class = "mb-3">
            <label asp-for ="inventoryName"></label>
            <input asp-for = "inventoryName" />
            <label asp-for ="finalPrize"></label>
            <input asp-for = "finalPrize" />
            <label asp-for ="inventoryDesc"></label>
            <input asp-for = "inventoryDesc" />
            <p>1 för "Transport</p>
            <p>2 för "Smycken"</p>
            <p>3 för "Hushåll"</p>
            <p>4 för "Dekoration"</p>
            <select asp-for = "categoryId">
                <option>1</option>
                <option>2</option>
                <option>3</option>
                <option>4</option>
            </select>
        </div>
        <button type = "submit" class = "btn btn-primary" width = "100px">Update</button>
        <a asp-controller = "Inventory" asp-action = "index" class = "btn btn-secondary" style = "width: 100px">Back to products</a> 
    </div>

</form>

2

Answers


  1. You have to add a primary key inventoryId as a hidden input, without this key , you inventory instance looks like a new one for EF.
    And since you are using [ValidateAntiForgeryToken] in the action, add this to view with another form syntax

    @using (Html.BeginForm("Edit", "Inventory", FormMethod.Post))
    {
     @Html.AntiForgeryToken()
    <input type="hidden" asp-for="inventoryId" value="@Model.inventoryId" />
    
    ....
    
    
      <button type = "submit" class = "btn btn-primary" width = "100px">Update</button>
    <a asp-controller = "Inventory" asp-action = "index" class = "btn btn-secondary" style = "width: 100px">Back to products</a> 
        </div>
    }
    
    

    and IMHO your update code could be like this

    if (ModelState.IsValid) 
    {
     var inventoryFromDb = _db.Inventories.Find(inventory.inventoryId);
    if (inventoryFromDb == null)
    {
        return NotFound();
     }
        _db.Entry(inventoryFromDb).CurrentValues.SetValues(inventory);
       var result=  _db.SaveChanges();
    }
    
    Login or Signup to reply.
  2. You have to send your record id to the controller by clicking update button of the record . something like this :

    <a class="btn btn-warning btn-sm btn-margin" asp-controller="ContextController" asp-action="UpdateAction" ***asp-route-id="@item.Id***">Update</a>
    

    which @item is the object of the model sent to the view .
    And the action would be :

    [HttpGet]
    public IActionResult UpdateAction(int id)
        {
            Model record = _Context.GetById(id);
            return View("UpdateFormPageOrModal",record);
        }
    

    And after updating the form and clicking the submit button of the view data will send to action :

    [HttpPost]
    public IActionResult UpdateAction(Model record)
        {     
                var result = _Context.UpdateBy(record);
                ViewData["Result"] = result.Message;
                if (result.IsSucceeded)
                {
                    _UnitOfWork.Save();
                    return RedirectToAction("TheGridView");
                }
                return View("UpdateView",record);
         }
    

    where UpdateBy() method should be like this :

    public void UpdateBy(T entity)//entity is an object of the DbSet<Model>
            {
                var state = _Context.Entry(entity).State;
                if (state == EntityState.Detached)
                {
                    _Context.Attach(entity);
                }
                _Context.Entry(entity).State = EntityState.Modified;
            }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search