问题
I am running into an issue that I cannot seem to wrap my head around. I am using Razor Pages and have two objects that can be bound.
[BindProperty]
public MeetingMinuteInputDto MeetingToCreate { get; set; }
[BindProperty]
public MeetingMinuteUpdateDto MeetingToUpdate { get; set; }
Above two are separate dto for creating/updating a base entity in my database. I have two separate dto because I allow only specific items for update (to prevent overposting). Both classes have a Name
, Date
, and Reminder
. The MeetingMinuteUpdateDto
only allows the Date
to be changed.
The Name property is required and cannot be null. The reason I have both objects in the same page/controller is because I am using modals to create/update and I would rather not create multiple pages just to create/edit objects.
I have two forms that users can fill out - one for editing and one for creating. Each one binds the values to a specific object (i.e. the create form will bind its posted form values to the 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>
Above is a sample of my form for the creating a new meeting. I checked to see that when the form is submitted, only the MeetingMinuteInputDto
value is being bound to. The other object (MeetingMinuteUpdateDto
) has null values for all its properties.
But when I check the model state, MVC throws an error on the "Name" property saying that it is null. I looked at the results of the model state and there is a key named "Name" which is not tied to any object that fails validation.
If I remove the other object (i.e. I remove MeetingMinuteUpdateDto
) from the page and do model binding, everything works correctly. How do I prevent the model validation from trying to validate an objects that is not relevant for the current action? I want the Create action to only validate the create object and vice versa.
I tried doing TryValidateModel(MeetingToCreate)
but that also provides a false for model validation.
Note: I can't just place the object properties outside as I have other pages where I need to do this in which the update/create objects have 10+ properties that are shared/not shared.
Update - I can manually remove the validation error from the model state dictionary. But I don't really like that approach as I don't want to have to iterate through all the properties for the incorrect keys and remove them.
Update 2: Here is more detail on when this issue is occurring:
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; }
}
In my Razor Page, I have both of these properties with the bind property attribute:
public class MeetingMinutesModel : PageModel
{
[BindProperty]
public MeetingMinuteInputDto MeetingToCreate { get; set; }
[BindProperty]
public MeetingMinuteUpdateDto MeetingToUpdate { get; set; }
//...stuff
}
My form on the create/edit page looks as such:
<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>
The input for the form is set to bind specifically to the MeetingToCreate property. When I submit the form, the form values are correctly bound. But at the same time, I am getting ModelState errors for the MeetingToUpdate
property (as it shares some fields with MeetingToCreate
).
I am assuming that in a Razor Page, model state validation is validating the MeetingMinutesModel and not the individual MeetingToCreate/MeetingToUpdate
properties. In MVC, I assume this might be different as actions need to have parameters as opposed to open-ended properties on the page model in razor pages.
回答1:
I was doing something similar. Searching for any solution, I find your question, but not a solution I share the solution.
I implement multiple BindProperty and multiple Actions OnPost, and the solution I find is to do some in the Asp.Net MVC, using the [Bind] property.
In your case, it would be.
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
}
回答2:
In Razor pages , @model in the page is PageModel and the "Name" property of MeetingMinuteManipulationDto
class is Required
, so model state validation validates all the properties in the PageModel .
If you insist on the original idea , you could try to use ViewComponent to implement create/edit objects in the same razor view.
来源:https://stackoverflow.com/questions/54068385/razor-pages-model-validation-fails-due-to-multiple-objects-sharing-parameters