我遇到了一个似乎无法解决的问题。我正在使用Razor Pages,并且有两个可以绑定的对象。
[BindProperty]
public MeetingMinuteInputDto MeetingToCreate { get; set; }
[BindProperty]
public MeetingMinuteUpdateDto MeetingToUpdate { get; set; }
以上两个是单独的dto,用于在数据库中创建/更新基本实体。我有两个单独的dto,因为我只允许特定的项目进行更新(以防止发布过多)。这两个类都有一个Name
,Date
和Reminder
。 MeetingMinuteUpdateDto
仅允许更改Date
。
名称属性是必需的,不能为null。我在同一页面/控制器中同时拥有两个对象的原因是,因为我使用模态来创建/更新,所以我宁愿不要仅创建/编辑对象就创建多个页面。
我有两种用户可以填写的表格-一种用于编辑,一种用于创建。每个人都将值绑定到特定对象(即创建表单会将其发布的表单值绑定到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会在“名称”属性上引发错误,指出它为null。我查看了模型状态的结果,有一个名为“名称”的键,该键不与任何未通过验证的对象绑定。
如果我从页面中删除另一个对象(即,我删除了MeetingMinuteUpdateDto
)并进行了模型绑定,则一切正常。如何防止模型验证尝试验证与当前操作无关的对象?我希望“创建”操作仅验证创建对象,反之亦然。
我尝试做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中,我认为这可能有所不同,因为操作需要具有参数,而不是剃刀页面中页面模型上的开放式属性。
答案 0 :(得分:1)
我正在做类似的事情。在搜索任何解决方案时,我会找到您的问题,但我没有共享解决方案。
我实现了多个BindProperty和多个Actions OnPost, 我发现的解决方案是使用[Bind]属性在Asp.Net MVC中进行一些操作。
以您的情况为准。
public class MeetingMinutesModel : PageModel
{
//[BindProperty] remove it
public MeetingMinuteInputDto MeetingToCreate { get; set; }
//[BindProperty] remove it
public MeetingMinuteUpdateDto MeetingToUpdate { get; set; }
//...stuff
}
public IActionResult OnPost([Bind("Name, FileToUpload, AdditionalInfo")] MeetingMinuteInputDto MeetingToCreate)
{
//Do somthing
}
答案 1 :(得分:0)
在Razor页面中,页面中的@model是 PageModel ,而MeetingMinuteManipulationDto
类的“ Name” 属性是Required
,因此模型状态验证将验证PageModel中的所有属性。
如果您坚持最初的想法,则可以尝试使用ViewComponent在同一剃刀视图中实现创建/编辑对象。