ModelState.IsValid 对于发送带有隐藏输入的 Id 为 false

问题描述 投票:0回答:2

我刚刚开始学习 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();

    }


}
c# asp.net asp.net-core
2个回答
1
投票

但是书籍的 ID 是通过“索引”页面的 URL 传递的 在“编辑”页面中我可以看到 URL 中的值。

PageModel 中的

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" />

0
投票

您可以将 id 属性用作不可为 null 的属性,因为 CLR 不确定该属性是否为 null,因此它假定它无效。

public async Task OnGet(int? id)
{
    Book = await _db.Book.FindAsync(id);
}
© www.soinside.com 2019 - 2024. All rights reserved.