Description
Hi,
I want to create an api with multiple result types
with using TypedResults
, but seems, .net core 7 only supports ValidationProblem
for generating swagger metadata automatically and ProblemHttpResult
type doesn't generate any swagger metadata. Maybe we need to declare dedicated problem types like ValidationProblem
for others, like InternalProbelm
, UnAuthorizedProblem
, ...
async Task<Results<CreatedAtRoute<CreateProductResponse>, ProblemHttpResult>>
Handle([AsParameters] CreateProductRequestParameters requestInput)
{
///...
return TypedResults.CreatedAtRoute(
new CreateProductResponse(result.Id),
"GetProductById",
new {id = result.Id});
}
I had to handle it manually for myself like this (we have some limitation because ProblemHttpResult
is sealed class and I can't inherit from it directly, so I created a HttpProblemResultBase
for replacement, also ProducesResponseTypeMetadata
was internal, and I had to create a custom one):
public class HttpProblemResultBase :
IResult,
IStatusCodeHttpResult,
IContentTypeHttpResult,
IValueHttpResult,
IEndpointMetadataProvider,
IValueHttpResult<ProblemDetails>
{
private readonly ProblemHttpResult _problem;
public HttpProblemResultBase(
int statusCode,
string? title = null,
string? type = null,
string? detail = null,
string? instance = null,
IDictionary<string, object?>? extensions = null
)
{
_problem = TypedResults.Problem(
statusCode: statusCode,
title: title,
type: type,
detail: detail,
instance: instance,
extensions: extensions);
}
public Task ExecuteAsync(HttpContext httpContext)
{
return _problem.ExecuteAsync(httpContext);
}
public ProblemDetails ProblemDetails => _problem.ProblemDetails;
public virtual int? StatusCode => _problem.StatusCode;
public string ContentType => _problem.ContentType;
object IValueHttpResult.Value => ProblemDetails;
public ProblemDetails Value => ProblemDetails;
public static void PopulateMetadata(MethodInfo method, EndpointBuilder builder)
{
method.NotNull();
builder.NotNull();
builder.Metadata.Add(new ResponseMetadata(StatusCodes.Status500InternalServerError, typeof(ProblemDetails)));
}
}
public class InternalHttpProblemResult : HttpProblemResultBase
{
public InternalHttpProblemResult(
string? title = null,
string? type = null,
string? detail = null,
string? instance = null,
IDictionary<string, object?>? extensions = null
) : base(StatusCodes.Status500InternalServerError, title, type, detail, instance, extensions)
{
}
}
public class NotFoundHttpProblemResult : HttpProblemResultBase
{
public NotFoundHttpProblemResult(
string? title = null,
string? type = null,
string? detail = null,
string? instance = null,
IDictionary<string, object?>? extensions = null
) : base(StatusCodes.Status404NotFound, title, type, detail, instance, extensions)
{
}
}
And my route now should be for generating swagger metadata for problems automatically:
async Task<Results<CreatedAtRoute<CreateProductResponse>, UnAuthorizedHttpProblemResult, ValidationProblem>>
Handle([AsParameters] CreateProductRequestParameters requestInput)
{
///...
return TypedResults.CreatedAtRoute(
new CreateProductResponse(result.Id),
"GetProductById",
new {id = result.Id});
}