Id 与对象作为 Delete HTTP Post 中的参数。哪个更好?
Id vs Object as parameters in Delete HTTP Post. Which is better?
作为初学者,我正在尝试使用 ASP.net Core 实现一个简单的 CRUD。我的问题是一个名为 DeletePlayer() 的 HTTP post。请考虑下面我的代码:
型号:
public class Player
{
public int PlayerId { get; set; }
//... deleted unrelated code for shorter post ...
}
控制器:
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");
}
}
查看:
@model Player_Simulation.Models.Player
<form method="post" asp-action="DeletePlayer">
<input asp-for="PlayerId" hidden />
<div class="border p-3">
<div class="form-group row">
<h2 class="text-black-50 pl-3">Delete Player</h2>
</div>
<div class="row">
<div class="col-12">
<div class="form-group row">
<div class="col-6">
<label asp-for="PlayerName"></label>
</div>
<div class="col-6">
<label asp-for="PlayerRating"></label>
</div>
</div>
<div class="form-group row">
<div class="col-6">
<input asp-for="PlayerName" disabled class="form-control" />
</div>
<div class="col-6">
<input asp-for="PlayerRating" disabled class="form-control" />
</div>
</div>
<div class="form-group row">
<div class="col-8 offset-2 row">
<div class="col">
<input type="submit" class="btn btn-danger w-75" value="Delete" />
</div>
<div class="col">
<a asp-action="PlayerIndex" class="btn btn-success w-75">Back</a>
</div>
</div>
</div>
</div>
</div>
</div>
图形:
我的 PlayerController 中的 DeletePlayer(int?id) 不起作用,它给我 HTTP 错误 404。但是,如果我将其更改为:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult DeletePlayer(Player obj)
{
_database.Players.Remove(obj);
_database.SaveChanges();
return RedirectToAction("PlayerIndex");
}
删除有效!所以我的问题是:
- 为什么 DeletePlayer(int?id) 不工作而 DeletePlayer(Player obj) 工作?
- 如果我想让 DeletePlayer(int?id) 起作用,我必须做什么?
如果有人能帮助我解决我的困惑,我将不胜感激!
1.Why doesn't DeletePlayer(int? id) work while DeletePlayer(Player obj) work?
尝试在DeletePlayer(int? id)
HttpPost方法中设置断点,点击删除按钮时是否命中断点?
如果这个断点没有命中,说明路由有错误,路由没有找到这个action方法,需要检查请求url和action名称
如果遇到断点,检查id值,可能id为null,所以if条件会return一个NotFound错误。 id 为空的原因可能是请求 url (路由模板)不包含 ID 值,并且提交表单不包含 id 字段。因此,id 将为空。
您正在使用表单提交删除,这将尝试发送整个模型,因此 DeletePlayer(Player obj) 起作用。
2.What must I do if I want DeletePlayer(int? id) to work?
解决办法就是你在例子中看到的,就是在DeletePlayer方法中添加ActionName("Delete")属性。该属性为路由系统执行映射,以便包含 POST 请求的 /Delete/ 的 URL 将找到 DeletePlayer 方法。
结果:
从上面的例子我们可以看到,在删除Get页面中,请求url是https://localhost:5001/Player/Delete/2
,点击删除按钮后,提交请求url会是https://localhost:5001/Player/Delete/2
,所以在HttpPost方法中,我们可以从请求url(路由数据)中获取id值,而不是提交的表单
参考:https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/details?view=aspnetcore-5.0
作为初学者,我正在尝试使用 ASP.net Core 实现一个简单的 CRUD。我的问题是一个名为 DeletePlayer() 的 HTTP post。请考虑下面我的代码:
型号:
public class Player
{
public int PlayerId { get; set; }
//... deleted unrelated code for shorter post ...
}
控制器:
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");
}
}
查看:
@model Player_Simulation.Models.Player
<form method="post" asp-action="DeletePlayer">
<input asp-for="PlayerId" hidden />
<div class="border p-3">
<div class="form-group row">
<h2 class="text-black-50 pl-3">Delete Player</h2>
</div>
<div class="row">
<div class="col-12">
<div class="form-group row">
<div class="col-6">
<label asp-for="PlayerName"></label>
</div>
<div class="col-6">
<label asp-for="PlayerRating"></label>
</div>
</div>
<div class="form-group row">
<div class="col-6">
<input asp-for="PlayerName" disabled class="form-control" />
</div>
<div class="col-6">
<input asp-for="PlayerRating" disabled class="form-control" />
</div>
</div>
<div class="form-group row">
<div class="col-8 offset-2 row">
<div class="col">
<input type="submit" class="btn btn-danger w-75" value="Delete" />
</div>
<div class="col">
<a asp-action="PlayerIndex" class="btn btn-success w-75">Back</a>
</div>
</div>
</div>
</div>
</div>
</div>
图形:
我的 PlayerController 中的 DeletePlayer(int?id) 不起作用,它给我 HTTP 错误 404。但是,如果我将其更改为:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult DeletePlayer(Player obj)
{
_database.Players.Remove(obj);
_database.SaveChanges();
return RedirectToAction("PlayerIndex");
}
删除有效!所以我的问题是:
- 为什么 DeletePlayer(int?id) 不工作而 DeletePlayer(Player obj) 工作?
- 如果我想让 DeletePlayer(int?id) 起作用,我必须做什么?
如果有人能帮助我解决我的困惑,我将不胜感激!
1.Why doesn't DeletePlayer(int? id) work while DeletePlayer(Player obj) work?
尝试在DeletePlayer(int? id)
HttpPost方法中设置断点,点击删除按钮时是否命中断点?
如果这个断点没有命中,说明路由有错误,路由没有找到这个action方法,需要检查请求url和action名称
如果遇到断点,检查id值,可能id为null,所以if条件会return一个NotFound错误。 id 为空的原因可能是请求 url (路由模板)不包含 ID 值,并且提交表单不包含 id 字段。因此,id 将为空。
您正在使用表单提交删除,这将尝试发送整个模型,因此 DeletePlayer(Player obj) 起作用。
2.What must I do if I want DeletePlayer(int? id) to work?
解决办法就是你在例子中看到的,就是在DeletePlayer方法中添加ActionName("Delete")属性。该属性为路由系统执行映射,以便包含 POST 请求的 /Delete/ 的 URL 将找到 DeletePlayer 方法。
结果:
从上面的例子我们可以看到,在删除Get页面中,请求url是https://localhost:5001/Player/Delete/2
,点击删除按钮后,提交请求url会是https://localhost:5001/Player/Delete/2
,所以在HttpPost方法中,我们可以从请求url(路由数据)中获取id值,而不是提交的表单
参考:https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/details?view=aspnetcore-5.0