I am trying to implement a simple CRUD using ASP.net Core as a beginner. My issue is with an HTTP post called DeletePlayer(). Please consider my code below:
Model:
public class Player
{
public int PlayerId { get; set; }
//... deleted unrelated code for shorter post ...
}
Controller:
public class PlayerController : Controller
{
private readonly DataContext _database;
public PlayerController(DataContext database)
{
_database = database;
}
//... deleted unrelated code for shorter post ...
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult DeletePlayer(int? id)
{
if (id == null || id == 0)
{
return NotFound();
}
var obj = _database.Players.Find(id);
if (obj == null)
{
return NotFound();
}
_database.Players.Remove(obj);
_database.SaveChanges();
return RedirectToAction("PlayerIndex");
}
}
View:
@model Player_Simulation.Models.Player
<form method="post" asp-action="DeletePlayer">
<input asp-for="PlayerId" hidden />
<div >
<div >
<h2 >Delete Player</h2>
</div>
<div >
<div >
<div >
<div >
<label asp-for="PlayerName"></label>
</div>
<div >
<label asp-for="PlayerRating"></label>
</div>
</div>
<div >
<div >
<input asp-for="PlayerName" disabled />
</div>
<div >
<input asp-for="PlayerRating" disabled />
</div>
</div>
<div >
<div >
<div >
<input type="submit" value="Delete" />
</div>
<div >
<a asp-action="PlayerIndex" >Back</a>
</div>
</div>
</div>
</div>
</div>
</div>
Graphics:
The DeletePlayer(int? id) I have in my PlayerController doesn't work and it gives me HTTP ERROR 404. However, if I change that to:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult DeletePlayer(Player obj)
{
_database.Players.Remove(obj);
_database.SaveChanges();
return RedirectToAction("PlayerIndex");
}
The delete works! So my questions are:
- Why doesn't DeletePlayer(int? id) work while DeletePlayer(Player obj) work?
- What must I do if I want DeletePlayer(int? id) to work?
I would appreciate anyone who could help me with my confusions!
CodePudding user response:
1.Why doesn't DeletePlayer(int? id) work while DeletePlayer(Player obj) work?
Try to set a breakpoint in the DeletePlayer(int? id)
HttpPost method, whether this breakpoint is hit when you click the Delete button?
If this breakpoint doesn't hit, it means there have a route error, the route doesn't find this action method, you need to check the request url and the action name.
If the breakpoint is hit, check the id value, perhaps the id is null, so the if condition will return a NotFound error. The reason for the empty id could be that the request url (route template) doesn’t contains the ID value, and the submit form doesn’t contains the id field. So, the id will be null.
You are using a form submit for your delete and that will attempt to send the entire model, so DeletePlayer(Player obj) work.
2.What must I do if I want DeletePlayer(int? id) to work?
The solution is what you see in the example, which is to add the ActionName("Delete") attribute to the DeletePlayer method. That attribute performs mapping for the routing system so that a URL that includes /Delete/ for a POST request will find the DeletePlayer method.
result:
From the above sample, we can see that in the Delete Get page, the request url is https://localhost:5001/Player/Delete/2
, after clicking the delete button, the submit request url will be https://localhost:5001/Player/Delete/2
, so in the HttpPost method, we can get the id value from the request url (route data), instead of the submitted form.
refer to:https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/details?view=aspnetcore-5.0