I'm not quite sure if this is possible to do but wanted to check. I have a razor page that has a few different handler methods. In some of them, I return a partial view result.
Example:
public class BoardMeetingsModel : PageModel
{
//ctor
//properties
public IActionResult OnGetFetchCreateMeetingPartial()
{
return Partial("_CreateMeetingPartial", new ManipulationDto());
}
}
My partial view is setup as below:
@using Models.ManipulationModels
@model ManipulationDto
It's a partial page so I am not using the @page directive (partial page is named _CreateMeetingPartial.cshtml
. When I pass in the ManipulationModel though, I run into below error
The model item passed into the ViewDataDictionary is of type 'Models.ManipulationDto', but this ViewDataDictionary instance requires a model item of type 'Pages.BoardMeetingsModel'.
I am not calling the partial with my razor page. I am directly returning a partial page because I am consuming the returned data in a javascript modal. Is it even possible to override this behavior? By default it always expects the base PageModel
(i.e. BoardMeetingsModel) to be passed in.
I'm surprised that even though I am explicitly passing in a model that exists, the partial view is still expecting a pagemodel instead of the model I explicitly stated for the partial view.
This appears to be bug in newly introduced Partial()
in ASP.NET Core 2.2 where model parameter seems to be completely redundant, because "this" is the only thing it will accept.
If you however use PartialViewResult()
it will work. Should be simpler and more readable than the accepted solution.
Just swap this
return Partial("_CreateMeetingPartial", new ManipulationDto());
with this
return new PartialViewResult
{
ViewName = "_CreateMeetingPartial",
ViewData = new ViewDataDictionary<ManipulationDto>(ViewData, new ManipulationDto())
};
To resolve above issue, I had to do below. Note that I do not have [BindProperty] attribute on my ManipulationDto property because I have multiple models on my page. If you have multiple models and you have validation (e.g. required properties), all of them will trigger in razor pages which is different from MVC. The way to handle it in my case was to pass the model directly as a parameter but also making sure to have a public property which I can assign all the values in case model state validation fails.
If you do not have multiple unique models, each with their own validation, you can just apply the bindproperty attribute and not worry.
public class BoardMeetingsModel : PageModel
{
//this gets initialized to a new empty object in the constructor (i.e. MeetingToManipulate = new ManipulationDto();)
public ManipulationDto MeetingToManipulate { get; set; }
//ctor
//properties
public IActionResult OnGetFetchCreateMeetingPartial(ManipulationDto meetingToManipulate)
{
//send the page model as the object as razor pages expects
//the page model as the object value for partial result
return Partial("_CreateMeetingPartial", this);
}
public async Task<IActionResult> OnPostCreateMeetingAsync(CancellationToken cancellationToken, ManipulationDto MeetingToCreate)
{
if (!ModelState.IsValid)
{
//set the pagemodel property to be the values submitted by the user
//not doing this will cause all model state errors to be lost
this.MeetingToManipulate = MeetingToCreate;
return Partial("_CreateMeetingPartial", this);
}
//else continue
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With