Skip to content

Add TBuilder overloads to WithTags and others #41830

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

Merged
merged 3 commits into from
Jun 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 70 additions & 54 deletions src/Http/Routing/src/Builder/OpenApiRouteHandlerBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,23 @@ public static class OpenApiRouteHandlerBuilderExtensions
{
private static readonly ExcludeFromDescriptionAttribute _excludeFromDescriptionMetadataAttribute = new();

/// <summary>
/// Adds the <see cref="IExcludeFromDescriptionMetadata"/> to <see cref="EndpointBuilder.Metadata"/> for all endpoints
/// produced by <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="IEndpointConventionBuilder"/>.</param>
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
public static TBuilder ExcludeFromDescription<TBuilder>(this TBuilder builder) where TBuilder : IEndpointConventionBuilder
=> builder.WithMetadata(_excludeFromDescriptionMetadataAttribute);

/// <summary>
/// Adds the <see cref="IExcludeFromDescriptionMetadata"/> to <see cref="EndpointBuilder.Metadata"/> for all endpoints
/// produced by <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="RouteHandlerBuilder"/>.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder ExcludeFromDescription(this RouteHandlerBuilder builder)
{
builder.WithMetadata(_excludeFromDescriptionMetadataAttribute);

return builder;
}
=> ExcludeFromDescription<RouteHandlerBuilder>(builder);

/// <summary>
/// Adds an <see cref="IProducesResponseTypeMetadata"/> to <see cref="EndpointBuilder.Metadata"/> for all endpoints
Expand All @@ -40,9 +45,10 @@ public static RouteHandlerBuilder ExcludeFromDescription(this RouteHandlerBuilde
/// <param name="additionalContentTypes">Additional response content types the endpoint produces for the supplied status code.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
#pragma warning disable RS0026
public static RouteHandlerBuilder Produces<TResponse>(this RouteHandlerBuilder builder,
public static RouteHandlerBuilder Produces<TResponse>(
#pragma warning restore RS0026
int statusCode = StatusCodes.Status200OK,
this RouteHandlerBuilder builder,
int statusCode = StatusCodes.Status200OK,
string? contentType = null,
params string[] additionalContentTypes)
{
Expand All @@ -60,9 +66,10 @@ public static RouteHandlerBuilder Produces<TResponse>(this RouteHandlerBuilder b
/// <param name="additionalContentTypes">Additional response content types the endpoint produces for the supplied status code.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
#pragma warning disable RS0026
public static RouteHandlerBuilder Produces(this RouteHandlerBuilder builder,
public static RouteHandlerBuilder Produces(
#pragma warning restore RS0026
int statusCode,
this RouteHandlerBuilder builder,
int statusCode,
Type? responseType = null,
string? contentType = null,
params string[] additionalContentTypes)
Expand All @@ -74,13 +81,10 @@ public static RouteHandlerBuilder Produces(this RouteHandlerBuilder builder,

if (contentType is null)
{
builder.WithMetadata(new ProducesResponseTypeMetadata(responseType ?? typeof(void), statusCode));
return builder;
return builder.WithMetadata(new ProducesResponseTypeMetadata(responseType ?? typeof(void), statusCode));
}

builder.WithMetadata(new ProducesResponseTypeMetadata(responseType ?? typeof(void), statusCode, contentType, additionalContentTypes));

return builder;
return builder.WithMetadata(new ProducesResponseTypeMetadata(responseType ?? typeof(void), statusCode, contentType, additionalContentTypes));
}

/// <summary>
Expand All @@ -91,16 +95,14 @@ public static RouteHandlerBuilder Produces(this RouteHandlerBuilder builder,
/// <param name="statusCode">The response status code.</param>
/// <param name="contentType">The response content type. Defaults to "application/problem+json".</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder ProducesProblem(this RouteHandlerBuilder builder,
int statusCode,
string? contentType = null)
public static RouteHandlerBuilder ProducesProblem(this RouteHandlerBuilder builder, int statusCode, string? contentType = null)
{
if (string.IsNullOrEmpty(contentType))
{
contentType = "application/problem+json";
}

return Produces<ProblemDetails>(builder, statusCode, contentType);
return Produces(builder, statusCode, typeof(ProblemDetails), contentType);
}

/// <summary>
Expand All @@ -111,7 +113,8 @@ public static RouteHandlerBuilder ProducesProblem(this RouteHandlerBuilder build
/// <param name="statusCode">The response status code. Defaults to <see cref="StatusCodes.Status400BadRequest"/>.</param>
/// <param name="contentType">The response content type. Defaults to "application/problem+json".</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder ProducesValidationProblem(this RouteHandlerBuilder builder,
public static RouteHandlerBuilder ProducesValidationProblem(
this RouteHandlerBuilder builder,
int statusCode = StatusCodes.Status400BadRequest,
string? contentType = null)
{
Expand All @@ -120,9 +123,24 @@ public static RouteHandlerBuilder ProducesValidationProblem(this RouteHandlerBui
contentType = "application/problem+json";
}

return Produces<HttpValidationProblemDetails>(builder, statusCode, contentType);
return Produces(builder, statusCode, typeof(HttpValidationProblemDetails), contentType);
}

/// <summary>
/// Adds the <see cref="ITagsMetadata"/> to <see cref="EndpointBuilder.Metadata"/> for all endpoints
/// produced by <paramref name="builder"/>.
/// </summary>
/// <remarks>
/// The OpenAPI specification supports a tags classification to categorize operations
/// into related groups. These tags are typically included in the generated specification
/// and are typically used to group operations by tags in the UI.
/// </remarks>
/// <param name="builder">The <see cref="IEndpointConventionBuilder"/>.</param>
/// <param name="tags">A collection of tags to be associated with the endpoint.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static TBuilder WithTags<TBuilder>(this TBuilder builder, params string[] tags) where TBuilder : IEndpointConventionBuilder
=> builder.WithMetadata(new TagsAttribute(tags));

/// <summary>
/// Adds the <see cref="ITagsMetadata"/> to <see cref="EndpointBuilder.Metadata"/> for all endpoints
/// produced by <paramref name="builder"/>.
Expand All @@ -136,10 +154,7 @@ public static RouteHandlerBuilder ProducesValidationProblem(this RouteHandlerBui
/// <param name="tags">A collection of tags to be associated with the endpoint.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder WithTags(this RouteHandlerBuilder builder, params string[] tags)
{
builder.WithMetadata(new TagsAttribute(tags));
return builder;
}
=> WithTags<RouteHandlerBuilder>(builder, tags);

/// <summary>
/// Adds <see cref="IAcceptsMetadata"/> to <see cref="EndpointBuilder.Metadata"/> for all endpoints
Expand All @@ -150,12 +165,12 @@ public static RouteHandlerBuilder WithTags(this RouteHandlerBuilder builder, par
/// <param name="contentType">The request content type that the endpoint accepts.</param>
/// <param name="additionalContentTypes">The list of additional request content types that the endpoint accepts.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder Accepts<TRequest>(this RouteHandlerBuilder builder,
string contentType, params string[] additionalContentTypes) where TRequest : notnull
public static RouteHandlerBuilder Accepts<TRequest>(
this RouteHandlerBuilder builder,
string contentType,
params string[] additionalContentTypes) where TRequest : notnull
{
Accepts(builder, typeof(TRequest), contentType, additionalContentTypes);

return builder;
return Accepts(builder, typeof(TRequest), contentType, additionalContentTypes);
}

/// <summary>
Expand All @@ -168,12 +183,13 @@ public static RouteHandlerBuilder Accepts<TRequest>(this RouteHandlerBuilder bui
/// <param name="contentType">The request content type that the endpoint accepts.</param>
/// <param name="additionalContentTypes">The list of additional request content types that the endpoint accepts.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder Accepts<TRequest>(this RouteHandlerBuilder builder,
bool isOptional, string contentType, params string[] additionalContentTypes) where TRequest : notnull
public static RouteHandlerBuilder Accepts<TRequest>(
this RouteHandlerBuilder builder,
bool isOptional,
string contentType,
params string[] additionalContentTypes) where TRequest : notnull
{
Accepts(builder, typeof(TRequest), isOptional, contentType, additionalContentTypes);

return builder;
return Accepts(builder, typeof(TRequest), isOptional, contentType, additionalContentTypes);
}

/// <summary>
Expand All @@ -185,11 +201,13 @@ public static RouteHandlerBuilder Accepts<TRequest>(this RouteHandlerBuilder bui
/// <param name="contentType">The request content type that the endpoint accepts.</param>
/// <param name="additionalContentTypes">The list of additional request content types that the endpoint accepts.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder Accepts(this RouteHandlerBuilder builder,
Type requestType, string contentType, params string[] additionalContentTypes)
public static RouteHandlerBuilder Accepts(
this RouteHandlerBuilder builder,
Type requestType,
string contentType,
params string[] additionalContentTypes)
{
builder.WithMetadata(new AcceptsMetadata(requestType, false, GetAllContentTypes(contentType, additionalContentTypes)));
return builder;
return Accepts(builder, requestType, isOptional: false, contentType, additionalContentTypes);
}

/// <summary>
Expand All @@ -202,38 +220,36 @@ public static RouteHandlerBuilder Accepts(this RouteHandlerBuilder builder,
/// <param name="contentType">The request content type that the endpoint accepts.</param>
/// <param name="additionalContentTypes">The list of additional request content types that the endpoint accepts.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder Accepts(this RouteHandlerBuilder builder,
Type requestType, bool isOptional, string contentType, params string[] additionalContentTypes)
public static RouteHandlerBuilder Accepts(
this RouteHandlerBuilder builder,
Type requestType,
bool isOptional,
string contentType,
params string[] additionalContentTypes)
{
builder.WithMetadata(new AcceptsMetadata(requestType, isOptional, GetAllContentTypes(contentType, additionalContentTypes)));
return builder;
var contentTypes = GetAllContentTypes(contentType, additionalContentTypes);
return builder.WithMetadata(new AcceptsMetadata(requestType, isOptional, contentTypes));
}

/// <summary>
/// Adds <see cref="IEndpointDescriptionMetadata"/> to <see cref="EndpointBuilder.Metadata"/> for all endpoints
/// produced by <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="RouteHandlerBuilder"/>.</param>
/// <param name="builder">The <see cref="IEndpointConventionBuilder"/>.</param>
/// <param name="description">A string representing a detailed description of the endpoint.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder WithDescription(this RouteHandlerBuilder builder, string description)
{
builder.WithMetadata(new EndpointDescriptionAttribute(description));
return builder;
}
public static TBuilder WithDescription<TBuilder>(this TBuilder builder, string description) where TBuilder : IEndpointConventionBuilder
=> builder.WithMetadata(new EndpointDescriptionAttribute(description));

/// <summary>
/// Adds <see cref="IEndpointSummaryMetadata"/> to <see cref="EndpointBuilder.Metadata"/> for all endpoints
/// produced by <paramref name="builder"/>.
/// </summary>
/// <param name="builder">The <see cref="RouteHandlerBuilder"/>.</param>
/// <param name="builder">The <see cref="IEndpointConventionBuilder"/>.</param>
/// <param name="summary">A string representing a brief description of the endpoint.</param>
/// <returns>A <see cref="RouteHandlerBuilder"/> that can be used to further customize the endpoint.</returns>
public static RouteHandlerBuilder WithSummary(this RouteHandlerBuilder builder, string summary)
{
builder.WithMetadata(new EndpointSummaryAttribute(summary));
return builder;
}
public static TBuilder WithSummary<TBuilder>(this TBuilder builder, string summary) where TBuilder : IEndpointConventionBuilder
=> builder.WithMetadata(new EndpointSummaryAttribute(summary));

private static string[] GetAllContentTypes(string contentType, string[] additionalContentTypes)
{
Expand Down
6 changes: 4 additions & 2 deletions src/Http/Routing/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ static Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.MapPatch(this
override Microsoft.AspNetCore.Routing.RouteValuesAddress.ToString() -> string?
*REMOVED*~Microsoft.AspNetCore.Routing.DefaultInlineConstraintResolver.DefaultInlineConstraintResolver(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Routing.RouteOptions!>! routeOptions, System.IServiceProvider! serviceProvider) -> void
Microsoft.AspNetCore.Routing.DefaultInlineConstraintResolver.DefaultInlineConstraintResolver(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Routing.RouteOptions!>! routeOptions, System.IServiceProvider! serviceProvider) -> void
static Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ExcludeFromDescription<TBuilder>(this TBuilder builder) -> TBuilder
static Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithDescription<TBuilder>(this TBuilder builder, string! description) -> TBuilder
static Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithSummary<TBuilder>(this TBuilder builder, string! summary) -> TBuilder
static Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithTags<TBuilder>(this TBuilder builder, params string![]! tags) -> TBuilder
static Microsoft.AspNetCore.Http.RouteHandlerFilterExtensions.AddFilter(this Microsoft.AspNetCore.Builder.RouteHandlerBuilder! builder, Microsoft.AspNetCore.Http.IRouteHandlerFilter! filter) -> Microsoft.AspNetCore.Builder.RouteHandlerBuilder!
static Microsoft.AspNetCore.Http.RouteHandlerFilterExtensions.AddFilter(this Microsoft.AspNetCore.Builder.RouteHandlerBuilder! builder, System.Func<Microsoft.AspNetCore.Http.RouteHandlerContext!, Microsoft.AspNetCore.Http.RouteHandlerFilterDelegate!, Microsoft.AspNetCore.Http.RouteHandlerFilterDelegate!>! filterFactory) -> Microsoft.AspNetCore.Builder.RouteHandlerBuilder!
static Microsoft.AspNetCore.Http.RouteHandlerFilterExtensions.AddFilter(this Microsoft.AspNetCore.Builder.RouteHandlerBuilder! builder, System.Func<Microsoft.AspNetCore.Http.RouteHandlerInvocationContext!, Microsoft.AspNetCore.Http.RouteHandlerFilterDelegate!, System.Threading.Tasks.ValueTask<object?>>! routeHandlerFilter) -> Microsoft.AspNetCore.Builder.RouteHandlerBuilder!
static Microsoft.AspNetCore.Http.RouteHandlerFilterExtensions.AddFilter<TFilterType>(this Microsoft.AspNetCore.Builder.RouteHandlerBuilder! builder) -> Microsoft.AspNetCore.Builder.RouteHandlerBuilder!
static Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithDescription(this Microsoft.AspNetCore.Builder.RouteHandlerBuilder! builder, string! description) -> Microsoft.AspNetCore.Builder.RouteHandlerBuilder!
static Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithSummary(this Microsoft.AspNetCore.Builder.RouteHandlerBuilder! builder, string! summary) -> Microsoft.AspNetCore.Builder.RouteHandlerBuilder!
static Microsoft.AspNetCore.Routing.LinkGeneratorEndpointNameAddressExtensions.GetPathByName(this Microsoft.AspNetCore.Routing.LinkGenerator! generator, Microsoft.AspNetCore.Http.HttpContext! httpContext, string! endpointName, Microsoft.AspNetCore.Routing.RouteValueDictionary? values = null, Microsoft.AspNetCore.Http.PathString? pathBase = null, Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null) -> string?
static Microsoft.AspNetCore.Routing.LinkGeneratorEndpointNameAddressExtensions.GetPathByName(this Microsoft.AspNetCore.Routing.LinkGenerator! generator, string! endpointName, Microsoft.AspNetCore.Routing.RouteValueDictionary? values = null, Microsoft.AspNetCore.Http.PathString pathBase = default(Microsoft.AspNetCore.Http.PathString), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null) -> string?
static Microsoft.AspNetCore.Routing.LinkGeneratorEndpointNameAddressExtensions.GetUriByName(this Microsoft.AspNetCore.Routing.LinkGenerator! generator, Microsoft.AspNetCore.Http.HttpContext! httpContext, string! endpointName, Microsoft.AspNetCore.Routing.RouteValueDictionary? values = null, string? scheme = null, Microsoft.AspNetCore.Http.HostString? host = null, Microsoft.AspNetCore.Http.PathString? pathBase = null, Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null) -> string?
Expand Down
Loading