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
});
}
}
}
}
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.ExecuteAsyncmethod as theMicrosoft.AspNetCore.Http.HttpValidationProblemDetailsbut 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: