【发布时间】:2019-06-01 18:19:31
【问题描述】:
我遇到了一个我似乎无法解决的问题。我正在使用 Razor Pages 并且有两个可以绑定的对象。
[BindProperty]
public MeetingMinuteInputDto MeetingToCreate { get; set; }
[BindProperty]
public MeetingMinuteUpdateDto MeetingToUpdate { get; set; }
以上两个是单独的 dto,用于在我的数据库中创建/更新基本实体。我有两个单独的 dto,因为我只允许更新特定项目(以防止过度发布)。这两个类都有Name、Date 和Reminder。 MeetingMinuteUpdateDto 只允许更改 Date。
Name 属性是必需的,不能为空。我在同一个页面/控制器中拥有两个对象的原因是因为我使用模式来创建/更新,我宁愿不创建多个页面只是为了创建/编辑对象。
我有两种用户可以填写的表格 - 一种用于编辑,另一种用于创建。每一个都将值绑定到一个特定的对象(即创建表单会将其发布的表单值绑定到MeetingMinuteInputDto)。
<div class="form-group">
<div class="col-md-10">
<label asp-for="MeetingToCreate.Name" class="control-label"></label>
<input asp-for="MeetingToCreate.Name" class="form-control" />
<span asp-validation-for="MeetingToCreate.Name" class="text-danger"></span>
</div>
</div>
以上是我创建新会议的表单示例。我检查了提交表单时,只绑定了MeetingMinuteInputDto 值。另一个对象 (MeetingMinuteUpdateDto) 的所有属性都具有空值。
但是当我检查模型状态时,MVC 会在“名称”属性上抛出一个错误,指出它为空。我查看了模型状态的结果,并且有一个名为“Name”的键,它与任何未通过验证的对象无关。
如果我从页面中删除另一个对象(即我删除 MeetingMinuteUpdateDto)并进行模型绑定,那么一切正常。如何防止模型验证尝试验证与当前操作无关的对象?我希望 Create 操作仅验证创建对象,反之亦然。
我尝试过TryValidateModel(MeetingToCreate),但这也为模型验证提供了错误。
注意:我不能只将对象属性放在外面,因为我有其他需要执行此操作的页面,其中更新/创建对象有 10 多个共享/不共享属性.
更新 - 我可以手动从模型状态字典中删除验证错误。但我不太喜欢这种方法,因为我不想遍历所有属性以获取不正确的键并删除它们。
更新 2:以下是有关此问题发生时间的更多详细信息:
public class MeetingMinuteInputDto: MeetingMinuteManipulationDto
{
public string AdditionalInfo { get; set; }
}
public class MeetingMinuteUpdateDto : MeetingMinuteManipulationDto
{
}
public class MeetingMinuteManipulationDto
{
[Required]
public string Name { get; set; }
public IFormFile FileToUpload { get; set; }
}
在我的 Razor 页面中,这两个属性都带有 bind 属性:
public class MeetingMinutesModel : PageModel
{
[BindProperty]
public MeetingMinuteInputDto MeetingToCreate { get; set; }
[BindProperty]
public MeetingMinuteUpdateDto MeetingToUpdate { get; set; }
//...stuff
}
我在创建/编辑页面上的表单如下所示:
<form asp-page="/MeetingMinute/MeetingMinutes" asp-page-handler="CreateMeeting">
<div class="form-group">
<div class="col-md-10">
<label asp-for="MeetingToCreate.Name" class="control-label"></label>
<input asp-for="MeetingToCreate.Name" class="form-control" />
<span asp-validation-for="MeetingToCreate.Name" class="text-danger"></span>
</div>
</div>
//other inputs and label for rest of the properties
<button type="submit" class="btn btn-danger">Submit</button>
</form>
表单的输入设置为专门绑定到 MeetingToCreate 属性。当我提交表单时,表单值已正确绑定。但与此同时,MeetingToUpdate 属性出现 ModelState 错误(因为它与 MeetingToCreate 共享一些字段)。
我假设在 Razor 页面中,模型状态验证正在验证 MeetingMinutesModel 而不是单个 MeetingToCreate/MeetingToUpdate 属性。在 MVC 中,我认为这可能会有所不同,因为操作需要有参数,而不是 razor 页面中页面模型上的开放式属性。
【问题讨论】:
-
与其将这些作为属性添加到 PageModel,不如将它们作为 Create 和 Update 操作方法的参数。
-
@MikeBrind 我需要将它们作为公共参数,因为我需要在我的剃刀视图中访问它们。由于 razor 视图仅接受 razor 页面模型作为模型,如果它们是操作级别参数,我将如何访问视图中的这些值?
-
您能否分享可以重现该问题的更相关的代码?
-
@XueliChen 详情请看我的最新更新
-
@DC_AC 没有找到任何允许我使用具有共享属性名称的模型的解决方案。我选择创建一个具有共享属性名称的类,以便它可以用于两个对象,具体取决于调用的页面操作。我相信整个页面本身就是正在验证的“模型”,而不是单个属性,但我必须深入研究源代码来确认这一点。
标签: c# asp.net-core asp.net-core-mvc razor-pages