You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Razor Pages商品编辑异常:必填项验证错误与ID归零

商品编辑功能问题排查与修复

问题现象

  1. 编辑商品时,所有字段均已填写,但仍弹出「请填写所有必填字段」提示
  2. 提交编辑请求后,页面显示的商品ID变为0

问题原因及修复方案

1. 必填字段验证失败

  • Category字段未初始化:OnGet方法仅给SelectedCategory赋值,但页面表单绑定的是ProductDTO.Category,导致该字段初始为空,触发[Required]验证规则。
  • ImageFile被强制要求必填:ProductDTO中ImageFile标记了[Required],但编辑场景下无需强制上传新图片,未上传时会触发验证失败。

修复步骤:

  • 移除ProductDTO中ImageFile的[Required]属性
  • 在OnGet方法中给ProductDTO.Category赋值,确保表单初始显示正确分类

2. 商品ID变为0

  • 表单未传递商品ID:页面中ID仅作为纯文本显示,未添加可提交的字段,导致OnPost方法无法获取到ID参数;同时验证失败时,Product对象未重新赋值,页面显示默认初始化的Id=0。

修复步骤:

  • 在表单中添加隐藏字段传递商品ID
  • OnPost验证失败时,重新从数据库获取商品信息并赋值给Model.Product

修改后的关键代码片段

ProductDTO

public class ProductDTO
{
    [Required]
    public string Name { get; set; }
    [Required]
    public string Brand { get; set; }

    public string? Description { get; set; }
    [Required]
    public string Category { get; set; }

    public Product.Category ProductCategory { get; set; }
    [Required]
    public string Gender { get; set; }
    [Required]
    public double Price { get; set; }
    // 移除必填属性,编辑时可选上传图片
    public IFormFile? ImageFile { get; set; }
}

EditModel.cshtml.cs - OnGet方法

public void OnGet(int? id)
{
    if (id == null)
    {
        Response.Redirect("/Admin/Products/Index");
        return;
    }

    var product = context.Products.Find(id);

    if (product == null)
    {
        Response.Redirect("/Admin/Products/Index");
        return;
    }

    ProductDTO.Name = product.Name;
    ProductDTO.Brand = product.Brand;
    ProductDTO.Description = product.Description;
    // 给ProductDTO.Category赋值,确保表单初始选中正确分类
    ProductDTO.Category = product.ProductCategory.ToString();
    ProductDTO.Price = product.Price;
    ProductDTO.Gender = product.Gender;

    Product = product;
}

EditModel.cshtml.cs - OnPost方法

public void OnPost(int? id) 
{
    if (id == null)
    {
        Response.Redirect("/Admin/Products/Index");
        return;
    }

    var product = context.Products.Find(id); 
    if (product == null) 
    {
        Response.Redirect("/Admin/Products/Index");
        return;
    }

    if (!ModelState.IsValid)
    {
        errorMessage = "Please complete all required fields";
        // 验证失败时重新赋值Product,确保页面显示正确ID
        Product = product;
        // 保留用户已输入的字段值
        ProductDTO.Name = ProductDTO.Name ?? product.Name;
        ProductDTO.Brand = ProductDTO.Brand ?? product.Brand;
        ProductDTO.Description = ProductDTO.Description ?? product.Description;
        ProductDTO.Category = ProductDTO.Category ?? product.ProductCategory.ToString();
        ProductDTO.Price = ProductDTO.Price == 0 ? product.Price : ProductDTO.Price;
        ProductDTO.Gender = ProductDTO.Gender ?? product.Gender;
        return;
    }

    // 更新图片逻辑(不变)
    string newFileName = product.ImageFileName;
    if (ProductDTO.ImageFile != null)
    {
        newFileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + Path.GetExtension(ProductDTO.ImageFile.FileName);
        string imageFullPath = environment.WebRootPath + "/products/" + newFileName;
        using (var stream = System.IO.File.Create(imageFullPath))
        {
            ProductDTO.ImageFile.CopyTo(stream);
        }
        string oldimageFullPath = environment.WebRootPath + "/products/" + product.ImageFileName;
        System.IO.File.Delete(oldimageFullPath);
    }

    // 更新商品信息,改用ProductDTO.Category
    product.Name = ProductDTO.Name;
    product.Brand = ProductDTO.Brand;
    product.Description = ProductDTO.Description ?? "";
    product.ProductCategory = (Product.Category)Enum.Parse(typeof(Product.Category), ProductDTO.Category);
    product.Price = ProductDTO.Price;
    product.Gender = ProductDTO.Gender;
    product.ImageFileName = newFileName;

    context.SaveChanges();
    successMessage = "Product updated successfully";
    Response.Redirect("/Admin/Products/Index");
}

Edit.cshtml - 表单添加隐藏ID字段

<form method="post" enctype="multipart/form-data">
    <!-- 添加隐藏字段传递商品ID -->
    <input type="hidden" asp-for="Product.Id" />
    
    <div class="row mb-3">
        <label class="col-sm-4 col-form-label">ID</label>
        <div class="col-sm-8">
            <input readonly class="form-control-plaintext" value="@Model.Product.Id"/>
        </div>
    </div>
    
    <!-- 其他表单字段保持不变 -->
</form>

内容的提问来源于stack exchange,提问作者randomuser32323223

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 12:45:56