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

ProblemDetailsServiceEndpointFilter stripping HttpValidationProblemDetails #24

Open
kingdamo opened this issue Dec 13, 2022 · 2 comments

Comments

@kingdamo
Copy link

Hi @DamianEdwards,

I'm trying to use the ProblemDetailsServiceEndpointFilter inside of this repository and it mostly works great.

When I run the API, calling /test it returns a response of:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "Value1": [
      "Problem 1",
      "Problem 2"
    ]
  }
}

However if I use the /testfiltered if returns a response of:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400
}

While debugging I can see that it gets to the ProblemDetailsServiceAwareResult.ExecuteAsync method as the Microsoft.AspNetCore.Http.HttpValidationProblemDetails but then the extra validation properties are lost.

Even explicitly using that type as the Value type, it doesn't solve the problem.

Any help would be appreciated.

Regards,
Damien.

Program.cs:

using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerDocument();

builder.Services.AddProblemDetails(
);

var app = builder.Build();

app.UseExceptionHandler();
app.UseStatusCodePages();

if (app.Environment.IsDevelopment())
{
    app.UseOpenApi();
    app.UseSwaggerUi3();
}

app.MapGet("/test", () =>
{
    var dict = new Dictionary<string, string[]>();
    dict.Add("Value1", new[] { "Problem 1", "Problem 2" });

    return Results.ValidationProblem(dict);
});

var general = app.MapGroup("").AddEndpointFilter(new ProblemDetailsServiceEndpointFilter());

general.MapGet("/testfiltered", () =>
{
    var dict = new Dictionary<string, string[]>();
    dict.Add("Value1", new[] { "Problem 1", "Problem 2" });

    return Results.ValidationProblem(dict);
});

app.Run();

public class ProblemDetailsServiceEndpointFilter : IEndpointFilter
{
    public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
        => await next(context) switch
        {
            ProblemHttpResult problemHttpResult => new ProblemDetailsServiceAwareResult(problemHttpResult.StatusCode, problemHttpResult.ProblemDetails),
            ProblemDetails problemDetails => new ProblemDetailsServiceAwareResult(null, problemDetails),
            { } result => result,
            null => null
        };

    private class ProblemDetailsServiceAwareResult : IResult, IValueHttpResult, IValueHttpResult<ProblemDetails>
    {
        private readonly int? _statusCode;

        public ProblemDetailsServiceAwareResult(int? statusCode, ProblemDetails problemDetails)
        {
            _statusCode = statusCode ?? problemDetails.Status;
            Value = problemDetails;
        }

        public ProblemDetails Value { get; }

        object? IValueHttpResult.Value => Value;

        public async Task ExecuteAsync(HttpContext httpContext)
        {
            if (httpContext.RequestServices.GetService<IProblemDetailsService>() is IProblemDetailsService problemDetailsService)
            {
                if (_statusCode is { } statusCode)
                {
                    httpContext.Response.StatusCode = statusCode;
                }
                await problemDetailsService.WriteAsync(new()
                {
                    HttpContext = httpContext,
                    ProblemDetails = Value
                });
            }
        }
    }
}
Repository owner deleted a comment from mohammed-source Dec 13, 2022
Repository owner deleted a comment from mohammed-source Dec 13, 2022
Repository owner deleted a comment from mohammed-source Dec 13, 2022
Repository owner deleted a comment from mohammed-source Dec 13, 2022
Repository owner deleted a comment from mohammed-source Dec 18, 2022
Repository owner deleted a comment from mohammed-source Dec 19, 2022
@DamianEdwards
Copy link
Owner

Seems this is caused by an issue in ASP.NET Core itself: dotnet/aspnetcore#45680

Repository owner deleted a comment from mohammed-source Dec 20, 2022
Repository owner deleted a comment from mohammed-source Dec 20, 2022
Repository owner deleted a comment from mohammed-source Dec 20, 2022
@kingdamo
Copy link
Author

Seems this is caused by an issue in ASP.NET Core itself: [dotnet/aspnetcore#45680]

Thanks Damian, I'll follow on with that issue.

Repository owner deleted a comment from mohammed-source Dec 29, 2022
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

2 participants