Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type discriminator is lost when serializing a Result<T> using [TranslateResultToActionResult] #204

Open
uflowie opened this issue Sep 12, 2024 · 5 comments

Comments

@uflowie
Copy link

uflowie commented Sep 12, 2024

When serializing a derived type as its base type, System.Text.Json will use an extra type discriminator field to communicate the actual type of the serialized data. Given a base class Base and a derived type Derived, I have observed the following behavior:

  1. A controller endpoint returning Base will correctly include the type discriminator.
  2. A controller endpoint returning ActionResult<Base> will include the type discriminator.
  3. A controller endpoint returning Result<Base> will include the properties of the derived type but it will NOT include the type discriminator.

Minimal reproducible example: https://github.com/uflowie/ResultLostTypeDiscriminator

@ardalis
Copy link
Owner

ardalis commented Sep 12, 2024

Is this causing a real world problem? Your controllers should typically never return just an object and not an ActionRest, in order to support NotFound, etc.

@uflowie
Copy link
Author

uflowie commented Sep 12, 2024

Our controllers aren't returning just an object, they are returning a Result. But since the type discriminator for T is lost (unlike if I returned T directly), I cannot have polymorphic endpoints returning Result

@ardalis
Copy link
Owner

ardalis commented Sep 12, 2024

Right but based on what you're writing above, if they returned ActionResult<Result<T>> everything would work correctly.

@uflowie
Copy link
Author

uflowie commented Sep 13, 2024

ActionResult<Result<T>> does not work either, only ActionResult<T>

@marcelbarner
Copy link

I had a small look into it, the problem seems to be that in the ObjectResult the DeclaredType is null.

So when I add the DeclaredType to the ObjectResult I get the discriminator.

public ActionResult<WeatherForecast> Get(int id)
{
    var a = Result.Success<WeatherForecast>(new WeatherForecastDetails
    {
        Date = DateOnly.MaxValue,
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = "summ",
        RainingValue = id
    }).ToActionResult(this);
    ((ObjectResult)a.Result).DeclaredType = typeof(WeatherForecast);
    return a;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants