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

ASP.NET Core 6.0表单验证异常:出现不存在字段的必填错误

ASP.NET Core 6.0 Web应用表单验证异常问题

我正在开发一个ASP.NET Core 6.0 Web应用,表单验证功能出现异常。输出ModelState错误时,看到如下内容:

Key: Email, Error: The Email field is required.
Key: Password, Error: The Password field is required

这些错误并未显示在页面的任何表单下方。撰写问题期间我未修改任何代码,但不知为何下面这条错误不再出现,这让我更加困惑:

Key: Password, Error: The Password field is required.

我的编辑视图包含所有必要字段,但无论尝试何种方法都无法消除这些错误。

相关代码

编辑视图(Razor)

@model Replay.ViewModels.ApplicationUserRoleViewModel

@{    ViewData["Title"] = "Edit User";}

<h1>Edit User</h1>

<form asp-controller="Account" asp-action="Edit" method="post">    
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>    
    <div class="form-group">
        <label asp-for="ApplicationUser.Email" class="control-label"></label>
        <input asp-for="ApplicationUser.Email" class="form-control" />
        <span asp-validation-for="ApplicationUser.Email" class="text-danger"></span>
    </div>    
    <div class="form-group">
        <label asp-for="ApplicationUser.FullName" class="control-label"></label>
        <input asp-for="ApplicationUser.FullName" class="form-control" />
        <span asp-validation-for="ApplicationUser.FullName" class="text-danger"></span>
    </div>    
    <div class="form-group">
        <label asp-for="ApplicationUser.Password" class="control-label"></label>
        <input asp-for="ApplicationUser.Password" class="form-control" />
        <span asp-validation-for="ApplicationUser.Password" class="text-danger"></span>
    </div>    
    <div class="form-group">
        <label asp-for="ApplicationUser.Active" class="control-label"></label>
        <input asp-for="ApplicationUser.Active" type="checkbox" class="form-check-input" />
        <span asp-validation-for="ApplicationUser.Active" class="text-danger"></span>
    </div>

    <div class="form-group">
        <table>
            @for (int i = 0; i < Model.Roles.Count; i++)
            {
                <tr>
                    <td>
                        @Html.HiddenFor(m => m.Roles[i].Id)
                        @Html.HiddenFor(m => m.Roles[i].Name)
                        @Html.DisplayFor(m => m.Roles[i].Name)
                    </td>
                    <td>@Html.CheckBoxFor(m => m.Roles[i].Selected)</td>
                </tr>
            }
        </table>
    </div>

    <button type="submit" class="btn btn-primary">Save</button>
</form>

ViewModel代码

using Replay.Models;

namespace Replay.ViewModels
{
    public class ApplicationUserRoleViewModel
    {
        public ApplicationUser ApplicationUser { get; set; }
        public List<RoleViewModel> Roles { get; set; }

        public ApplicationUserRoleViewModel()
        {
        }

        public ApplicationUserRoleViewModel(ApplicationUser applicationUser, List<Role> roles, List<int> userRoleIds)
        {
            ApplicationUser = applicationUser;

            Roles = roles.Select(r => new RoleViewModel
            {
                Id = r.Id,
                Name = r.Name,
                Selected = userRoleIds.Contains(r.Id)
            }).ToList();
        }
    }

    public class RoleViewModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool Selected { get; set; }
    }
}

ApplicationUser模型

using System.ComponentModel.DataAnnotations;

namespace Replay.Models;

public class ApplicationUser
{
    [Key]
    public int Id { get; set; }
    public string Email { get; set; }
    public string FullName { get; set; }
    public string Password { get; set; }
    public Boolean Active { get; set; }
}

Role模型

using System.ComponentModel.DataAnnotations;

namespace Replay.Models
{
    public class Role
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

UserRole模型

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Replay.Models
{
    public class UserRole
    {
        [Key]
        public int Id { get; set; }
        [ForeignKey("ApplicationUser")]
        public int UserId { get; set; }
        [ForeignKey("Role")]
        public int RoleId { get; set; }
    }
}

控制器Edit方法

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(ApplicationUserRoleViewModel viewModel)
{
    if (!ModelState.IsValid)
    {
        foreach (var key in ModelState.Keys)
        {
            var state = ModelState[key];

            foreach (var error in state.Errors)
            {
                System.Diagnostics.Debug.WriteLine($"Key: {key}, Error: {error.ErrorMessage}");
            }

            var roles = _dbContext.Role.ToList();

            var userRoleIds = _dbContext.UserRoles
                                        .Where(ur => ur.UserId == viewModel.ApplicationUser.Id)
                                        .Select(ur => ur.RoleId).ToList();

            viewModel.Roles = roles.Select(r => new RoleViewModel
            {
                Id = r.Id,
                Name = r.Name,
                Selected = userRoleIds.Contains(r.Id)
            }).ToList();

            return View(viewModel);
        }
    }

    var user = _dbContext.ApplicationUser.Find(viewModel.ApplicationUser.Id);

    if (user == null)
    {
        return NotFound();
    }

    user.Email = viewModel.ApplicationUser.Email;
    user.FullName = viewModel.ApplicationUser.FullName;
    user.Password = viewModel.ApplicationUser.Password;
    user.Active = viewModel.ApplicationUser.Active;

    var userRoles = _dbContext.UserRoles.Where(ur => ur.UserId == user.Id).ToList();
    _dbContext.UserRoles.RemoveRange(userRoles);

    var selectedRoleIds = viewModel.Roles
                                   .Where(r => r.Selected)
                                   .Select(r => r.Id).ToList();

    foreach (var roleId in selectedRoleIds)
    {
        _dbContext.UserRoles.Add(new UserRole { UserId = user.Id, RoleId = roleId });
    }

    _dbContext.SaveChanges();

    return RedirectToAction("Index");
}

尝试过的解决方法

  • 移除所有表单组(即ApplicationUser.Email和ApplicationUser.Password),但仍会出现错误。值得注意的是,当从视图中移除这两个字段后,错误提示明确显示缺少ApplicationUser.Email、ApplicationUser.Password、Email和Password。
  • 尝试添加@Html.HiddenFor(),但无法编译,因为视图模型中没有Email和Password属性。
  • 尝试在ApplicationUser类的Email和Password属性后添加?。

预期结果

我希望模型验证通过,不会出现这种“幽灵字段”导致的验证失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 06:05:56