Skip to content

Commit fde9f39

Browse files
committed
Add generic variants of ProducesProblem and ProducesValidationProblem
1 parent 8d9db2f commit fde9f39

File tree

3 files changed

+70
-16
lines changed

3 files changed

+70
-16
lines changed

src/Http/Routing/src/Builder/OpenApiRouteHandlerBuilderExtensions.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,27 @@ public static RouteHandlerBuilder ProducesProblem(this RouteHandlerBuilder build
109109
return Produces(builder, statusCode, typeof(ProblemDetails), contentType);
110110
}
111111

112+
/// <summary>
113+
/// Adds an <see cref="IProducesResponseTypeMetadata"/> with a <see cref="ProblemDetails"/> type
114+
/// to <see cref="EndpointBuilder.Metadata"/> for all endpoints produced by <paramref name="builder"/>.
115+
/// </summary>
116+
/// <param name="builder">The <see cref="IEndpointConventionBuilder"/>.</param>
117+
/// <param name="statusCode">The response status code.</param>
118+
/// <param name="contentType">The response content type. Defaults to "application/problem+json".</param>
119+
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
120+
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
121+
public static TBuilder ProducesProblem<TBuilder>(this TBuilder builder, int statusCode, string? contentType = null)
122+
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
123+
where TBuilder : IEndpointConventionBuilder
124+
{
125+
if (string.IsNullOrEmpty(contentType))
126+
{
127+
contentType = "application/problem+json";
128+
}
129+
130+
return builder.WithMetadata(new ProducesResponseTypeMetadata(statusCode, typeof(ProblemDetails), [contentType]));
131+
}
132+
112133
/// <summary>
113134
/// Adds an <see cref="IProducesResponseTypeMetadata"/> with a <see cref="HttpValidationProblemDetails"/> type
114135
/// to <see cref="EndpointBuilder.Metadata"/> for all endpoints produced by <paramref name="builder"/>.
@@ -130,6 +151,30 @@ public static RouteHandlerBuilder ProducesValidationProblem(
130151
return Produces(builder, statusCode, typeof(HttpValidationProblemDetails), contentType);
131152
}
132153

154+
/// <summary>
155+
/// Adds an <see cref="IProducesResponseTypeMetadata"/> with a <see cref="HttpValidationProblemDetails"/> type
156+
/// to <see cref="EndpointBuilder.Metadata"/> for all endpoints produced by <paramref name="builder"/>.
157+
/// </summary>
158+
/// <param name="builder">The <see cref="IEndpointConventionBuilder"/>.</param>
159+
/// <param name="statusCode">The response status code. Defaults to <see cref="StatusCodes.Status400BadRequest"/>.</param>
160+
/// <param name="contentType">The response content type. Defaults to "application/problem+json".</param>
161+
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
162+
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
163+
public static TBuilder ProducesValidationProblem<TBuilder>(
164+
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
165+
this TBuilder builder,
166+
int statusCode = StatusCodes.Status400BadRequest,
167+
string? contentType = null)
168+
where TBuilder : IEndpointConventionBuilder
169+
{
170+
if (string.IsNullOrEmpty(contentType))
171+
{
172+
contentType = "application/problem+json";
173+
}
174+
175+
return builder.WithMetadata(new ProducesResponseTypeMetadata(statusCode, typeof(HttpValidationProblemDetails), [contentType]));
176+
}
177+
133178
/// <summary>
134179
/// Adds the <see cref="ITagsMetadata"/> to <see cref="EndpointBuilder.Metadata"/> for all endpoints
135180
/// produced by <paramref name="builder"/>.

src/Http/Routing/src/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ Microsoft.AspNetCore.Routing.ContentEncodingMetadata
33
Microsoft.AspNetCore.Routing.ContentEncodingMetadata.ContentEncodingMetadata(string! value, double quality) -> void
44
Microsoft.AspNetCore.Routing.ContentEncodingMetadata.Quality.get -> double
55
Microsoft.AspNetCore.Routing.ContentEncodingMetadata.Value.get -> string!
6+
static Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ProducesProblem<TBuilder>(this TBuilder builder, int statusCode, string? contentType = null) -> TBuilder
7+
static Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ProducesValidationProblem<TBuilder>(this TBuilder builder, int statusCode = 400, string? contentType = null) -> TBuilder
68
static Microsoft.AspNetCore.Routing.RouteHandlerServices.Map(Microsoft.AspNetCore.Routing.IEndpointRouteBuilder! endpoints, string! pattern, System.Delegate! handler, System.Collections.Generic.IEnumerable<string!>? httpMethods, System.Func<System.Reflection.MethodInfo!, Microsoft.AspNetCore.Http.RequestDelegateFactoryOptions?, Microsoft.AspNetCore.Http.RequestDelegateMetadataResult!>! populateMetadata, System.Func<System.Delegate!, Microsoft.AspNetCore.Http.RequestDelegateFactoryOptions!, Microsoft.AspNetCore.Http.RequestDelegateMetadataResult?, Microsoft.AspNetCore.Http.RequestDelegateResult!>! createRequestDelegate, System.Reflection.MethodInfo! methodInfo) -> Microsoft.AspNetCore.Builder.RouteHandlerBuilder!

src/Http/Routing/test/UnitTests/Builder/OpenApiRouteHandlerBuilderExtensionsTest.cs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,38 @@ public void Produces_AddsProducesResponseTypeMetadataWithVoidType()
6969
}
7070

7171
[Fact]
72-
public void ProdcesProblem_AddsProducesResponseTypeMetadataWithProblemDetailsType()
72+
public void ProducesProblem_AddsProducesResponseTypeMetadataWithProblemDetailsType()
7373
{
74-
var testBuilder = new TestEndointConventionBuilder();
75-
var builder = new RouteHandlerBuilder(new[] { testBuilder });
74+
static void GenericProducesProblem(IEndpointConventionBuilder builder) => builder.ProducesProblem(StatusCodes.Status400BadRequest);
75+
static void SpecificProducesProblem(RouteHandlerBuilder builder) => builder.ProducesProblem(StatusCodes.Status400BadRequest);
7676

77-
builder.ProducesProblem(StatusCodes.Status400BadRequest);
77+
static void AssertMetadata(EndpointBuilder builder)
78+
{
79+
var metadata = Assert.IsType<ProducesResponseTypeMetadata>(Assert.Single(builder.Metadata));
80+
Assert.Equal(typeof(ProblemDetails), metadata.Type);
81+
Assert.Equal(StatusCodes.Status400BadRequest, metadata.StatusCode);
82+
Assert.Equal("application/problem+json", Assert.Single(metadata.ContentTypes));
83+
}
84+
85+
RunWithBothBuilders(GenericProducesProblem, SpecificProducesProblem, AssertMetadata);
7886

79-
var metadata = Assert.IsType<ProducesResponseTypeMetadata>(Assert.Single(testBuilder.Metadata));
80-
Assert.Equal(typeof(ProblemDetails), metadata.Type);
81-
Assert.Equal(StatusCodes.Status400BadRequest, metadata.StatusCode);
82-
Assert.Equal("application/problem+json", Assert.Single(metadata.ContentTypes));
8387
}
8488

8589
[Fact]
86-
public void ProdcesValidiationProblem_AddsProducesResponseTypeMetadataWithHttpValidationProblemDetailsType()
90+
public void ProducesValidationProblem_AddsProducesResponseTypeMetadataWithHttpValidationProblemDetailsType()
8791
{
88-
var testBuilder = new TestEndointConventionBuilder();
89-
var builder = new RouteHandlerBuilder(new[] { testBuilder });
92+
static void GenericProducesProblem(IEndpointConventionBuilder builder) => builder.ProducesValidationProblem();
93+
static void SpecificProducesProblem(RouteHandlerBuilder builder) => builder.ProducesValidationProblem();
9094

91-
builder.ProducesValidationProblem();
95+
static void AssertMetadata(EndpointBuilder builder)
96+
{
97+
var metadata = Assert.IsType<ProducesResponseTypeMetadata>(Assert.Single(builder.Metadata));
98+
Assert.Equal(typeof(HttpValidationProblemDetails), metadata.Type);
99+
Assert.Equal(StatusCodes.Status400BadRequest, metadata.StatusCode);
100+
Assert.Equal("application/problem+json", Assert.Single(metadata.ContentTypes));
101+
}
92102

93-
var metadata = Assert.IsType<ProducesResponseTypeMetadata>(Assert.Single(testBuilder.Metadata));
94-
Assert.Equal(typeof(HttpValidationProblemDetails), metadata.Type);
95-
Assert.Equal(StatusCodes.Status400BadRequest, metadata.StatusCode);
96-
Assert.Equal("application/problem+json", Assert.Single(metadata.ContentTypes));
103+
RunWithBothBuilders(GenericProducesProblem, SpecificProducesProblem, AssertMetadata);
97104
}
98105

99106
[Fact]

0 commit comments

Comments
 (0)