我刚刚开始学习 asp.net core razor 页面并通过教程构建一个简单的项目。 该项目有一个用于编辑书籍的“编辑”剃刀页面。我试图将我的模型(书籍)的 Id 传递给具有隐藏输入的后处理程序,因为如果没有它,Book.Id 将为 0。但是当我使用 asp-for 标签助手执行此操作并点击更新时提交按钮,Model.IsValid 为 false。 但是当在“编辑”页面中我可以看到 URL 中的值时,书籍的 ID 是通过“索引”页面的 URL 传递的。 这是我的模型:
public class Book
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
public string Author { get; set; }
public string ISBN { get; set; }
}
和我的用于编辑的 cshtml:
<h2 class="text-info">Edit Book</h2>
<div class="container border m-3">
<form method="post">
<input asp-for="Book.Id" type="hidden"/>
<div class="row form-group mt-2">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<label for="title" class="col-sm-2 col-form-label " asp-for="Book.Title"></label>
<div class="col-sm-6">
<input asp-for="Book.Title" class="form-control" id="title"/>
<span asp-validation-for="Book.Title" class="text-danger"></span>
</div>
</div>
<div class="row form-group mt-2">
<label for="author" class="col-sm-2 col-form-label " asp-for="Book.Author"></label>
<div class="col-sm-6">
<input asp-for="Book.Author" class="form-control" id="author"/>
<span asp-validation-for="Book.Author" class="text-danger"></span>
</div>
</div>
<div class="row form-group mt-2">
<label for="ISBN" class="col-sm-2 col-form-label " asp-for="Book.ISBN"></label>
<div class="col-sm-6">
<input asp-for="Book.ISBN" class="form-control" id="ISBN"/>
<span asp-validation-for="Book.ISBN" class="text-danger"></span>
</div>
</div>
<div class="row ">
<div class="col-3 offset-2">
<input type="submit" value="Update" class="btn btn-primary form-control"/>
</div>
<div class="col-3 ">
<a asp-page="Index" class="btn btn-secondary form-control">Back To List</a>
</div>
</div>
</form>
@section scripts{
<partial name="_ValidationScriptsPartial" />
}
和我的cshtml.cs:
public class EditModel : PageModel
{
private readonly ApplicationDbContext _db;
public EditModel(ApplicationDbContext db)
{
_db = db;
}
[BindProperty]
public Book Book { get; set; }
public async Task OnGet(int id)
{
await _db.Book.FindAsync(id);
}
public async Task<IActionResult> OnPost()
{
if (ModelState.IsValid)
{
var bookFromDb = await _db.Book.FindAsync(Book.Id);
bookFromDb.Title = Book.Title;
bookFromDb.Author = Book.Author;
bookFromDb.ISBN = Book.ISBN;
await _db.SaveChangesAsync();
return RedirectToPage("Index");
}
return RedirectToPage();
}
}
PageModel 中的但是书籍的 ID 是通过“索引”页面的 URL 传递的 在“编辑”页面中我可以看到 URL 中的值。
Book
只会绑定来自一个源的数据。所以它不会绑定查询字符串中的数据。
第一种方式,如果
Book.Id
使用隐藏输入,则需要设置Book
的值。那么Book.Id
就会有值,否则发布时它是空字符串。更改如下:
public async Task OnGet(int id)
{
Book = await _db.Book.FindAsync(id);
}
另一种方式,您可以像
id
方法一样将 OnGet
设置为参数,然后将 id
设置为 Book.Id
:
public async Task<IActionResult> OnPost(int id)
{
Book.Id = id;
//...
return RedirectToPage();
}
这样,
Book.Id
的隐藏输入就没用了:
<input asp-for="Book.Id" type="hidden" />
您可以将 id 属性用作不可为 null 的属性,因为 CLR 不确定该属性是否为 null,因此它假定它无效。
public async Task OnGet(int? id)
{
Book = await _db.Book.FindAsync(id);
}