dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.19k stars 9.93k forks source link

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

Open ilya-scale opened 7 months ago

ilya-scale commented 7 months ago

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.

ghost commented 7 months ago

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis See info in area-owners.md if you want to be subscribed.

Issue Details
### Description If the property of the validated request is polymorphic, the validation would not work. ### Reproduction Steps ```csharp 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): ```json { "prop": { "type": "derived" } } ``` while a request to "test-request" results in 400 ("The Field field is required." which is correct): ```json { "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.
Author: ilya-scale
Assignees: -
Labels: `area-System.Text.Json`, `untriaged`
Milestone: -
eiriktsarpalis commented 7 months ago

Moving to the aspnetcore repo.