复杂对象的 Razor 页面验证错误,TryValidateModel() 不起作用
Razor Page validation error with a complex object, TryValidateModel() does not work
我正在构建 .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 页面中用于编辑 Location 对象的字段:
<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对象后,Organization.Name
字段也填充了非空字符串,应该可以通过验证。
我和这个问题斗争了几个小时,并且已经尝试过其他方法,比如 TryValidateModel(Location.Organization)
等等。
我正在寻找一种无需在表单中放置 Organization.Name
字段的方法。由于我的真实 Organization 对象中有更多其他字段,因此我不想将它们全部放在表单中。我也不想忽略验证错误。
我目前正在尝试了解 TryValidateModel()
是如何工作的,但是从源代码中找出来并不是很简单。
有解决问题的想法吗?
你可以尝试在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();
}
}
结果:
我正在构建 .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 页面中用于编辑 Location 对象的字段:
<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对象后,Organization.Name
字段也填充了非空字符串,应该可以通过验证。
我和这个问题斗争了几个小时,并且已经尝试过其他方法,比如 TryValidateModel(Location.Organization)
等等。
我正在寻找一种无需在表单中放置 Organization.Name
字段的方法。由于我的真实 Organization 对象中有更多其他字段,因此我不想将它们全部放在表单中。我也不想忽略验证错误。
我目前正在尝试了解 TryValidateModel()
是如何工作的,但是从源代码中找出来并不是很简单。
有解决问题的想法吗?
你可以尝试在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();
}
}
结果: