[英]Why does Controller 'Get' Edit method getting called twice in ASP.NET Core 6 MVC?
[英]Why is the ID parameter passed twice in the Edit() action method (POST) scaffold added by ASP.NET Core MVC?
我正在使用 Visual Studio 2019 中的 ASP.NET Core MVC 5.0。我让脚手架生成一个 controller 并使用 Entity Framework Core 进行 CRUD 操作。 我看到有两个Edit()
方法,方法的GET
版本在数据库中查找实体并将其传递给Edit
视图。 到目前为止,一切都说得通。 我有点困惑的是Edit()
方法的POST
版本。 这是它的签名和第一条语句的样子:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Name")] Department department)
{
if (id != department.Id)
{
return NotFound();
}
// ... (Removed for brevity)
}
如果可以使用 model 绑定将 ID 绑定到Department
实体,为什么它需要第一个int id
作为参数? 我已经尝试将它与相等检查一起删除,并且编辑仍然有效。 我还注意到我的Edit
视图中有一个隐藏的输入类型:
<input type="hidden" asp-for="Id" />
在删除id
参数后,我也尝试将其删除。 Edit()
不知何故仍然有效。 我想知道 ID 参数的用途, Edit()
方法中的相等性检查id == department.Id
以及Edit
视图中的隐藏输入字段。 我实际上想使用视图模型而不是直接将我的实体与BindAttribute
一起使用,但遇到了这种混乱。
我的实体称为Department
,它看起来像这样:
public class Department
{
public int Id { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "{0} is required")]
[StringLength(maximumLength: 100, MinimumLength = 1, ErrorMessage = "{0} should be between {2} and {1} characters")]
public string Name { get; set; }
public List<Course> Courses { get; set; }
}
有关更多上下文,这里是Edit()
的GET
版本的样子:
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var department = await _context.Departments.FindAsync(id);
if (department == null)
{
return NotFound();
}
return View(department);
}
首先,Edit View中的隐藏输入是在Post Edit方法中绑定department.Id。 因为你的部门有Id
属性,所以当你删除<input type="hidden" asp-for="Id" />
时,url中的Id仍然会绑定到department.Id和int Id。如果department.Id不存在, db 将创建一个新的。这是一个演示:
老师:
public class Teacher
{
public int TeacherId { get; set; }
public string TeacherName { get; set; }
public int TeacherAge { get; set; }
}
编辑:
<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="TeacherName" class="control-label"></label>
<input asp-for="TeacherName" class="form-control" />
<span asp-validation-for="TeacherName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="TeacherAge" class="control-label"></label>
<input asp-for="TeacherAge" class="form-control" />
<span asp-validation-for="TeacherAge" 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="Index">Back to List</a>
</div>
编辑方法:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("TeacherId,TeacherName,TeacherAge")] Teacher teacher)
{
if (ModelState.IsValid)
{
try
{
_context.Update(teacher);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TeacherExists(teacher.TeacherId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(teacher);
}
有时不是每个 model 都有一个名为Id
的属性作为主键,所以隐藏输入是必要的。
而id用来确保编辑的数据Id是正确的。例如,如果有人自定义页面,使Id可修改。或者有人更改隐藏输入的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.