Search code examples
asp.net-core-mvcentity-framework-core

ApplicationDbContext.Update() doesn't update but saves it as a new record


I am playing in the new APS.NET 5 RC1 environment but the default edit action creates a new entity of the object. I am searched the whole day finding where it goes wrong but I can't find out why it goes wrong.

Controller:

using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Data.Entity;
using SSTv5.Models;
using SSTv5.Models.Organisations;
using SSTv5.Models.Views;
using System.Collections.Generic;
using SSTv5.Models.Global;

namespace SSTv5.Controllers
{

public class OrganisationTypesController : Controller
{
    private ApplicationDbContext _context;
    private List<Breadcrumb> _bcList = new List<Breadcrumb>();

    public OrganisationTypesController(ApplicationDbContext context)
    {
        _context = context;    
    }

    #region Edit
    // GET: OrganisationTypes/Edit/5
    public async Task<IActionResult> Edit(int? id)
    {

        _bcList.Add(new Breadcrumb("OrganisationTypes", true, "Index", "Index"));
        _bcList.Add(new Breadcrumb("Edit", false));
        ViewBag.BcList = _bcList;

        if (id == null)
        {
            return HttpNotFound();
        }

        OrganisationType organisationType = await _context.OrganisationType.SingleAsync(m => m.OrganisationTypeId == id);
        if (organisationType == null)
        {
            return HttpNotFound();
        }
        return View(organisationType);
    }

    // POST: OrganisationTypes/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(OrganisationType organisationType)
    {
        if (ModelState.IsValid)
        {
            _context.Update(organisationType);
            await _context.SaveChangesAsync();
            return RedirectToAction("Index");
        }
        return View(organisationType);
    }
    #endregion
}
}

Form:

@model SSTv5.Models.Organisations.OrganisationType

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

<h2>Edit</h2>

<form asp-action="Edit">
<div class="form-horizontal">
    <h4>OrganisationType</h4>
    <hr />
    <div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="OrganisationTypeName" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input asp-for="OrganisationTypeName" class="form-control" />
            <span asp-validation-for="OrganisationTypeName" class="text-danger" />
        </div>
    </div>

    <div class="form-group">
        <label asp-for="ClassIcon" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input asp-for="ClassIcon" id="classIcon" />
            <span asp-validation-for="ClassIcon" class="text-danger" />
        </div>
    </div>

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

<div>
<a asp-action="Index">Back to List</a>
</div>

@section Scripts {
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
}

Solution

  • For anyone else who has this problem the answer is quite simple. The form doesn't send the ID of the object with it. The only thing you need to do is put the id in a hidden field in the form. Then it will work fine.