Skip to content

Asp.Net Core does not properly handle the error with polymorphic deserialization from STJ when type discriminator is not specified #54037

@ilya-scale

Description

@ilya-scale

Description

When type discriminator is not specified in the request, the error is not handled and 500 is returned instead of 400.

Example request 1:

{
	"type": "unknown",
	"someOtherProperty": "value"
}

Example request 2:

{
	"someOtherProperty": "value"
}

Controller action:

[HttpPost("test")]
public void Test(Base request)
{
        
}

Models:

[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
[JsonDerivedType(typeof(Derived), "derived")]
public abstract record Base
{
}

public record Derived : Base
{
}

Reproduction Steps

  1. Create a controller with the action and models from Description
  2. Do a call with the example request 1, response is 400
{
	"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
	"title": "One or more validation errors occurred.",
	"status": 400,
	"errors": {
		"$": [
			"Read unrecognized type discriminator id 'unknown'. Path: $ | LineNumber: 2 | BytePositionInLine: 21."
		],
		"request": [
			"The request field is required."
		]
	},
	"traceId": "00-a4e0c60070a4c53222d0622acad8d198-e18068d6fe5d5773-00"
}
  1. Do a call with the example request 2, response is 500
System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported.

Expected behavior

Ideally I expect the 400 error that will say clearly that the "type" TypeDiscriminator has to be provided (since the base class is abstract it is clear it cannot be constructed).

At the very least some form of 400 with json that tells that json cannot be deserialized instead of 500 (there was nothing "wrong" with the server, but client provided a bad request which is clearly a 400).

Actual behavior

A 500 is returned and the exception is not handled by asp.net core (unlike example 1 request)

Regression?

No response

Known Workarounds

One can probably make class not abstract and do a validation oneself that the "base" class is not supported.

Configuration

.Net 8
MacOS ARM

Other information

It is somewhat related to the case when type discriminator is not the first field. If it is not the first - it will be the same error I think, which should also be handled ideally, but this can be fixed in .Net 9 hopefully.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templates

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions