【问题标题】:Razor Page validation error with a complex object, TryValidateModel() does not work复杂对象的 Razor 页面验证错误,TryValidateModel() 不起作用
【发布时间】:2021-07-24 16:06:13
【问题描述】:

我正在构建 .Net 5 Razor Pages Web 应用程序并且有一个包含两个对象的结构:

public class Location
{
    public Guid Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    [ForeignKey("Organization")]
    public Guid OrganizationId { get; set; }

    public Organization Organization { get; set; }
}

public class Organization
{
   public Guid Id { get; set; }

   [Required]
   public string Name { get; set; }
}

以下是我的 Razor 页面中用于编辑位置对象的字段:

<input asp-for="Location.Organization.Id" class="hidden" value="@Model.Location.Organization.Id" />
<input asp-for="Location.Id" class="hidden" value="@Model.Location.Id" />
<input asp-for="Location.Name" class="form-control" value="@Model.Location.Name" />

我在页面上没有组织对象的字段。

在 OnPost() 方法中,我从数据库中填充组织对象并尝试再次验证模型。

Location.Organization = await _db.Organizations.FindAsync(Location.Organization.Id);

if (!TryValidateModel(Location, nameof(Location)))
{   
    return Page();
}

但它不起作用。模型仍然无效 (ModelState.IsValid != true)

验证错误说应该填写Organization.Name

但是 Location 对象中的所有字段都正确填写。填充组织对象后,Organization.Name 字段也填充了非空字符串,应该可以通过验证。

我与这个问题斗争了好几个小时,并且已经尝试过其他方式,比如TryValidateModel(Location.Organization)等等。

我正在寻找一种无需在表单中放置Organization.Name 字段的方法。由于我的真实组织对象中有更多其他字段,因此我不想将它们全部放入表单中。我也不想忽略验证错误。

我目前正在尝试了解TryValidateModel() 的工作原理,但从源代码中找出来并不容易。

有解决问题的方法吗?

【问题讨论】:

    标签: c# asp.net-core razor-pages


    【解决方案1】:

    您可以尝试在TryValidateModel(Location, nameof(Location))之前添加ModelState.Clear。这是一个演示:

    cshtml.cs:

    [BindProperty]
            public Location Location { get; set; }
            public void OnGet()
            {
                Location = new Location { Id = Guid.NewGuid(), Name = "loc", Organization = new Organization { Id = Guid.NewGuid() } };
            }
            public IActionResult OnPost()
            {
                Location.Organization = new Organization { Id = Location.Organization.Id, Name = "org" };
                ModelState.Clear();
                if (!TryValidateModel(Location, nameof(Location)))
                {
                    return Page();
                }
                else {
                    var s = ModelState.IsValid;
                    return Page();
                }
            }
    

    结果:

    【讨论】:

    • 你是对的,我已经测试过了,TryValidateModel() 有效。我之前用ModelState.Clear() 尝试过,但认为它不起作用,因为TryValidateModel() 之后的ModelState.Keys 列表为空。如果TryValidateModel() 之后没有验证错误,则ModelState.IsValid = trueModelState.Keys 为空。我认为它只是行不通。但是如果有错误,那么它们会在 Keys 中列出,ModelState 无效。非常感谢!很高兴知道。
    • 但我宁愿禁止对子对象进行验证。否则我需要用所有子对象填充整个结构。而且听起来不是很酷。
    • 我在这里创建了后续问题stackoverflow.com/q/67370045/2487565
    • 顺便说一句,很酷的视频!你用什么工具来捕捉它?
    猜你喜欢
    • 2019-12-16
    • 2022-07-20
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    • 2012-09-20
    • 1970-01-01
    相关资源
    最近更新 更多