Search code examples
c#asp.net-coremodel-bindingmediatr

Use non-default constructor for Razor Pages


I've got an asp.net core 2.2 web application using Razor Pages and Mediatr.

My query has private setters as described in Jimmy Bogard's blog:

public class Query : IRequest<Result>
{
    public Query(string needle)
    {
        this.Needle = needle;
    }

    public string Needle { get; private set; }
}

And when i use it in my web api it's OK (even ConstructionHandling is noneed)

But when i use Razor Pages i'got an error 'cause there's no parameterless ctor in query:

public class SearchModel : PageBaseModel
{
    public SearchModel(IMediator mediator)
        : base(mediator)
    {
    }

    [BindProperty(SupportsGet = true)]
    public Accounts.Search.Query Query { get; set; }

    public Accounts.Search.Result Result { get; private set; }

    public async Task<IActionResult> OnGetAsync(CancellationToken cancellationToken)
    {
        Result = await this.Mediator.Send(Query, cancellationToken);

        return this.Page();
    }
}

Is it possible to use private setters for model binding (without writting custom IModelBinder for every query)?


Solution

  • Is it possible to use private setters for model binding (without writting custom IModelBinder for every query)?

    emphasis mine

    Short answer: NO

    Long answer here Model Binding in ASP.NET Core: Complex types

    A complex type must have a public default constructor and public writable properties to bind. When model binding occurs, the class is instantiated using the public default constructor.

    again emphasis mine

    I believe how ever that you are mixing concerns by trying to use an immutable message request as a model for binding.