Skip to content

Asp.Net Core attribute validation does not work on polymorphic properties #54070

@ilya-scale

Description

@ilya-scale

Description

If the property of the validated request is polymorphic, the validation would not work.

Reproduction Steps

using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();

app.MapControllers();

app.Run();

[ApiController]
public class TestController : ControllerBase
{
    [HttpPost("test-property")]
    public void Test(Request request) { }

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

public record Request
{
    public required Base Prop { get; init; } 
}

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

public record Derived : Base
{
    
    [Required, StringLength(1)]
    public string? Field { get; init; }
}

One can use this code with these two payloads:

This request to "test-property" results in 200 (which is incorrect since the field "field" is not specified):

{
	"prop": {
		"type": "derived"
	}
}

while a request to "test-request" results in 400 ("The Field field is required." which is correct):

{
	"type": "derived"
}

Expected behavior

400 error and Validation of the Derived class properties even if it is a property of the original model.

Please note that without polymorphism (i.e. using Derived class directly instead of Base for Prop the validation works as expected.

Actual behavior

The Prop is not validated and 200 is returned

Regression?

No response

Known Workarounds

No response

Configuration

.Net 8

Other information

This issue came out of issue dotnet/runtime#98430 where another bug was identified for the Validator class (which does not go into properties at all). It was a suggestion by @eiriktsarpalis to split this bug into a separate one.

And just to avoid confusion: this is not a problem with System.Text.Json but with the ASP.Net Core validation of models and how they traverse the object being validated.

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions