-
|
Hello, I want to know why methods ValidationProblem produces different output when they are called on Results or TypedResults class. Results.ValidationProblem(errorMessages) produces {Microsoft.AspNetCore.Http.HttpResults.ProblemHttpResult} with {Microsoft.AspNetCore.Http.HttpValidationProblemDetails} in detail TypedResults.ValidationProblem(errorMessages) produces {Microsoft.AspNetCore.Http.HttpResults.ValidationProblem} with {Microsoft.AspNetCore.Http.HttpValidationProblemDetails} in detail. I have my own IProblemDetailsWriter registered in DI before default one and when I use method on Results class it is hit. But when the TypedResults method is used my writer is not hit. In my code I'm using Results but I want to use MinimalApis.Extensions for input parameters validation with DataAnnotations. And there is used TypedResults. using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Net;
var builder = WebApplication.CreateBuilder(args);
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IProblemDetailsWriter, ValidationDetailsWriter>());
builder.Services.AddProblemDetails();
var app = builder.Build();
app.MapGet("results", () => { return Results.ValidationProblem(new Dictionary<string, string[]> { { "test", ["test"] } }); });
app.MapGet("typedresults", () => { return TypedResults.ValidationProblem(new Dictionary<string, string[]> { { "test", ["test"] } }); });
app.Run();
internal class ValidationDetailsWriter : IProblemDetailsWriter
{
public bool CanWrite(ProblemDetailsContext context) => true;
public async ValueTask WriteAsync(ProblemDetailsContext context)
{
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
await context.HttpContext.Response.WriteAsync("My response");
}
}It looks like ProblemHttpResult is somewhere handled with ProblemDetailService but ValidationProblem not. Is there a way how to handle ValidationProblem with same ProblemDetailService? Thank you |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
|
When the result is of type that implement It's the case with The method public sealed class ProblemHttpResult : IResult, ...
{
...
public async Task ExecuteAsync(HttpContext httpContext)
{
var problemDetailsService = httpContext.RequestServices.GetService<IProblemDetailsService>();
if (problemDetailsService is null || !await problemDetailsService.TryWriteAsync(new() { HttpContext = httpContext, ProblemDetails = ProblemDetails }))
{
await HttpResultsHelper.WriteResultAsJsonAsync(
httpContext,
logger,
value: ProblemDetails,
ContentType);
}
}
}The method public sealed class ValidationProblem : IResult, ...
{
public Task ExecuteAsync(HttpContext httpContext)
{
return HttpResultsHelper.WriteResultAsJsonAsync(
httpContext,
logger,
value: ProblemDetails,
ContentType);
}
}It's similar, just As hack, it's possible to add a operation filter to convert app.MapGet("typedresults", () => { return TypedResults.ValidationProblem(new Dictionary<string, string[]> { { "test", ["test"] } }); })
.AddEndpointFilter(async (efiContext, next) =>
{
var result = await next(efiContext);
if(result is ValidationProblem vp)
{
return Results.Problem(vp.ProblemDetails);
}
return result;
});Can you specify your need? |
Beta Was this translation helpful? Give feedback.
-
|
There is an open issue and PR that will fix this: |
Beta Was this translation helpful? Give feedback.
When the result is of type that implement
IResult, the response is generated byIResult.ExecuteAsync.It's the case with
ProblemHttpResult(that is returned byResults.ValidationProblem) andValidationProblem(that is returned byTypedResults.ValidationProblem).The method
ProblemHttpResult.ExecuteAsyncis :