Aspnetcore: FromQuery deserializer requires empty constructor

Created on 26 Apr 2019  路  5Comments  路  Source: dotnet/aspnetcore

Hi guys 馃殌

Describe the bug

As in the title FromQuery requires empty constructor. It is weird because I can use constructors (which initialise all properties) for [FromBody].

System.InvalidOperationException: Could not create an instance of type 'FancyQuery'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Alternatively, give the 'query' parameter a non-null default value.

To Reproduce

Steps to reproduce the behavior:

  1. ASP.NET Core 2.2
  2. Controller and DTO/Command

```c#
// Controller method

[HttpGet("fancy")]
public async Task Find([FromQuery] FancyQuery query)
{
// TODO: add some action
return Ok();
}

// DTO
public class FancyQuery
{
public FancyQuery(int userId, int dumbValue)
{
UserId = userId;
DumbValue = dumbValue;
}

public int UserId { get; set; }
public int DumbValue { get; set; }

}

### Expected behavior
It should works like [FromBody].

### Additional context
Add any other context about the problem here.
Include the output of `dotnet --info`

.NET Core SDK (reflecting any global.json):
Version: 2.2.106
Commit: aa79b139a8

Runtime Environment:
OS Name: Mac OS X
OS Version: 10.14
OS Platform: Darwin
RID: osx.10.14-x64
Base Path: /usr/local/share/dotnet/sdk/2.2.106/

Host (useful for support):
Version: 2.2.4
Commit: f95848e524

.NET Core SDKs installed:
2.2.106 [/usr/local/share/dotnet/sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.2.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.2.4 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.2.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

```

By Design area-mvc

Most helpful comment

I can confirm this happens, and it is really frustrating.
When you work with DDD, you don't want people to instantiate your objects with a "default constructor" as this facilitates code corruption.
I think the behaviour should be the same as [FromBody].
Is it possible for us to suggest this? Maybe in a future release this can be changed.
Thank you.

All 5 comments

This is by design. FromBody uses serializers such as Newtonsoft.Json which have a different feature set compared to model binding. Model binding - indicated by FromQuery, FromRoute etc, requires that complex types have a parameterless constructor.

I can confirm this happens, and it is really frustrating.
When you work with DDD, you don't want people to instantiate your objects with a "default constructor" as this facilitates code corruption.
I think the behaviour should be the same as [FromBody].
Is it possible for us to suggest this? Maybe in a future release this can be changed.
Thank you.

did you try with a private or protected empty constructor ?

@hbsis-williamdasilva - same! But you can always use get variables and then initialize your DDD object. It's not a big deal.

@RemiBou I tried both, but it only works with a public empty constructor.
@rafalschmidt97 yes, it is not the end of the world, but it is kinda strange that you cannot use the same object for FromBody and FromQuery (for example).

The deal is, when using an object to deserialize using FromBody, normaly you dont wanna this object to be used inside your system. He is only an object to receive informations, that is why the private empty constructor is nice. No one can use this object.
Using FromQuery, you open this to other developers to instantiate this object.

Was this page helpful?
0 / 5 - 0 ratings