I am working on the CRUD functions in my ASP.NET Core application. I have this problem where when I try to edit a character (character is Karakter
in Dutch) the ID
of the character that I provide is always reset to 0. This is a problem because I now always edit the character with Id = 0 and I can't edit characters with an other id.
My view:
@model IEnumerable<Apex.Models.KarakterViewModel>
@{
ViewData["Title"] = "Karakter";
}
<h1>Karakter</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.KarakterId)
</th>
<th>
@Html.DisplayNameFor(model => model.KarakterSoort)
</th>
<th>
@Html.DisplayNameFor(model => model.KarakterNaam)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.KarakterId)
</td>
<td>
@Html.DisplayFor(modelItem => item.KarakterSoort)
</td>
<td>
@Html.DisplayFor(modelItem => item.KarakterNaam)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new {KarakterId = item.KarakterId}) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Home", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
</table>
My edit view:
@model Apex.Models.KarakterViewModel
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>KarakterViewModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="KarakterId" class="control-label"></label>
<input asp-for="KarakterId" class="form-control" />
<span asp-validation-for="KarakterId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="KarakterSoort" class="control-label"></label>
<input asp-for="KarakterSoort" class="form-control" />
<span asp-validation-for="KarakterSoort" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="KarakterNaam" class="control-label"></label>
<input asp-for="KarakterNaam" class="form-control" />
<span asp-validation-for="KarakterNaam" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Karakter">Back to List</a>
</div>
My controller:
public class KarakterController : Controller
{
private readonly IKarakterLogic _karakterLogic;
public KarakterController()
{
// Waarom moet apexfactory ervoor?
_karakterLogic = ApexFactory.ApexFactory.GetKarakterLogic();
}
public ActionResult Index()
{
return Karakter();
}
// GET: Karakter
public ActionResult Karakter()
{
var allKarakters = _karakterLogic.GetAllKarakters();
var karakters = new List<KarakterViewModel>();
foreach (var karakter in allKarakters)
{
karakters.Add(new KarakterViewModel
{
KarakterId = karakter.KarakterId,
KarakterNaam = karakter.KarakterNaam,
KarakterSoort = karakter.KarakterSoort
});
}
return View(karakters);
}
public ActionResult Delete(int KarakterId)
{
_karakterLogic.DeleteKarakter(KarakterId);
return RedirectToAction("Karakter");
}
[HttpGet]
public ActionResult Create()
{
var karakterViewModel = new KarakterViewModel();
return View(karakterViewModel);
}
[HttpPost]
public ActionResult Create(KarakterViewModel karakter)
{
_karakterLogic.CreateKarakter(karakter);
return RedirectToAction("Karakter");
}
[HttpGet]
public ActionResult Edit()
{
KarakterViewModel karakterViewModel = new KarakterViewModel();
_karakterLogic.GetById(karakterViewModel);
return View(karakterViewModel);
}
[HttpPost]
public ActionResult Edit(KarakterViewModel karakterViewModel)
{
_karakterLogic.UpdateKarakter(karakterViewModel);
return RedirectToAction("Karakter");
}
public ActionResult AllKarakters()
{
return Karakter();
}
}
My logic layer:
public class KarakterLogic : IKarakterLogic
{
private IKarakterContext karakterContext { get;}
public KarakterLogic(IKarakterContext context)
{
karakterContext = context;
}
public void CreateKarakter(IKarakter _karakter)
{
var karakter = new KarakterModel
{
KarakterNaam = _karakter.KarakterNaam,
KarakterSoort = _karakter.KarakterSoort
};
karakterContext.CreateKarakter(karakter);
}
public IEnumerable<IKarakter> GetAllKarakters()
{
return karakterContext.GetKarakters();
}
public IKarakter UpdateKarakter(IKarakter karakter)
{
karakterContext.UpdateKarakter(karakter);
return karakter;
}
public void DeleteKarakter(int KarakterId)
{
karakterContext.DeleteKarakter(KarakterId);
}
public IKarakter GetById(IKarakter karkter)
{
return karakterContext.GetById(karkter);
}
}
I think my logic and DAL are working fine, because it does edit the character with id 0 in the right way. The problem is that I don't only want to edit the character with id = 0.
How do I get it that I edit the character with the requested ID (and not the character with id 0.)?
Note: When I click the desired character (in this case the second character) my HTTP link is this:
So there it does recognize that the Id of the character I want to edit is 2. Can anyone help me?
Your code
@Html.ActionLink("Edit", "Edit", new {Id= item.KarakterId})
KarakterId
is passed as a parameter to the Edit
method, so you should receive it in the Edit
method, like this:
[HttpGet]
public ActionResult Edit(int Id)
{
//Get the corresponding ViewModel according to this Id, and then return to the view.
var allKarakters = _karakterLogic.GetAllKarakters();
var karakters = new List<KarakterViewModel>();
foreach (var karakter in allKarakters)
{
karakters.Add(new KarakterViewModel
{
KarakterId = karakter.KarakterId,
KarakterNaam = karakter.KarakterNaam,
KarakterSoort = karakter.KarakterSoort
});
}
var viewmodel=karakters.Where(c=>c.KarakterId==Id).FirstOrDefault();
return View(viewmodel);
}
This is just an example, you can write a method to get model based on Id
in your logic and then use it.