From c8390ab37bfcaff8467ed6ba4e4366ad0de6c5c0 Mon Sep 17 00:00:00 2001 From: salpelter Date: Thu, 16 Jan 2025 10:48:39 +0400 Subject: [PATCH 1/3] Fix inaccurate code snippet highlighting --- aspnetcore/fundamentals/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/fundamentals/index.md b/aspnetcore/fundamentals/index.md index 47d93591a374..421e9a219b64 100644 --- a/aspnetcore/fundamentals/index.md +++ b/aspnetcore/fundamentals/index.md @@ -71,7 +71,7 @@ The request handling pipeline is composed as a series of middleware components. By convention, a middleware component is added to the pipeline by invoking a `Use{Feature}` extension method. The use of methods named `Use{Feature}` to add middleware to an app is illustrated in the following code: -:::code language="csharp" source="~/fundamentals/index/samples/9.0/BlazorWebAppMovies/Program.cs" id="snippet_middleware" highlight="24-26,29,32"::: +:::code language="csharp" source="~/fundamentals/index/samples/9.0/BlazorWebAppMovies/Program.cs" id="snippet_middleware" highlight="26-28,30,32"::: For more information, see . From 0e2adf19a53e2c5d7b3d407d9b016d13ab8c945c Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Thu, 16 Jan 2025 13:08:47 -0600 Subject: [PATCH 2/3] Batch of small improvements to OpenAPI docs (#34507) * MaxLength and MinLength set maxItems / minItems on arrays * Better TOC in the Customization page * Add the Customize schema reuse section * Add doc on generating multiple OpenAPI documents * Apply suggestions from PR review Co-authored-by: Tom Dykstra --- .../openapi/aspnetcore-openapi.md | 36 ++++++++++++-- .../fundamentals/openapi/customize-openapi.md | 47 ++++++++++++++++--- .../fundamentals/openapi/include-metadata.md | 4 +- 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/aspnetcore/fundamentals/openapi/aspnetcore-openapi.md b/aspnetcore/fundamentals/openapi/aspnetcore-openapi.md index aa4decde9857..69a1295fc2d2 100644 --- a/aspnetcore/fundamentals/openapi/aspnetcore-openapi.md +++ b/aspnetcore/fundamentals/openapi/aspnetcore-openapi.md @@ -45,8 +45,8 @@ dotnet add package Microsoft.AspNetCore.OpenApi The following code: -* Adds OpenAPI services. -* Enables the endpoint for viewing the OpenAPI document in JSON format. +* Adds OpenAPI services using the extension method on the app builder's service collection. +* Maps an endpoint for viewing the OpenAPI document in JSON format with the extension method on the app. [!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_first&highlight=3,7)] @@ -64,7 +64,7 @@ Each OpenAPI document in an app has a unique name. The default document name tha builder.Services.AddOpenApi(); // Document name is v1 ``` -The document name can be modified by passing the name as a parameter to the `AddOpenApi` call. +The document name can be modified by passing the name as a parameter to the call. ```csharp builder.Services.AddOpenApi("internal"); // Document name is internal @@ -116,6 +116,36 @@ The OpenAPI document is regenerated every time a request to the OpenAPI endpoint [!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_mapopenapiwithcaching)] +## Generate multiple OpenAPI documents + +In some scenarios, it's helpful to generate multiple OpenAPI documents with different content from a single ASP.NET Core API app. These scenarios include: + +* Generating OpenAPI documentation for different audiences, such as public and internal APIs. +* Generating OpenAPI documentation for different versions of an API. +* Generating OpenAPI documentation for different parts of an application, such as a frontend and backend API. + +To generate multiple OpenAPI documents, call the extension method once for each document, specifying a different document name in the first parameter each time. + +```csharp +builder.Services.AddOpenApi("v1"); +builder.Services.AddOpenApi("v2"); +``` + +Each invocation of can specify its own set of options, so that you can choose to use the same or different customizations for each OpenAPI document. + +The framework uses the delegate method of to determine which endpoints to include in each document. + +For each document, the delegate method is called for each endpoint in the application, passing the object for the endpoint. The method returns a boolean value indicating whether the endpoint should be included in the document. The object contains information about the endpoint, such as the HTTP method, route, and response types, as well as metadata attached to the endpoint via attributes or extension methods. + +The default implementation of this delegate uses the field of , which is set on an endpoint using either the extension method or the attribute, to determine which endpoints to include in the document. Any endpoint that has not been assigned a group name is included all OpenAPI documents. + +```csharp + // Include endpoints without a group name or with a group name that matches the document name + ShouldInclude = (description) => description.GroupName == null || description.GroupName == DocumentName; +``` + +You can customize the delegate method to include or exclude endpoints based on any criteria you choose. + ## Generate OpenAPI documents at build-time In typical web applications, OpenAPI documents are generated at run-time and served via an HTTP request to the application server. diff --git a/aspnetcore/fundamentals/openapi/customize-openapi.md b/aspnetcore/fundamentals/openapi/customize-openapi.md index 1fc84999e7b8..92952162b52b 100644 --- a/aspnetcore/fundamentals/openapi/customize-openapi.md +++ b/aspnetcore/fundamentals/openapi/customize-openapi.md @@ -14,10 +14,6 @@ uid: fundamentals/openapi/customize-openapi ## OpenAPI document transformers -This section demonstrates how to customize OpenAPI documents with transformers. - -### Customize OpenAPI documents with transformers - Transformers provide an API for modifying the OpenAPI document with user-defined customizations. Transformers are useful for scenarios like: * Adding parameters to all operations in a document. @@ -50,7 +46,7 @@ Transformers execute in first-in first-out order based on registration. In the f [!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_transInOut&highlight=3-9)] -### Use document transformers +## Use document transformers Document transformers have access to a context object that includes: @@ -73,7 +69,7 @@ Document transformers are unique to the document instance they're associated wit [!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_multidoc_operationtransformer1)] -### Use operation transformers +## Use operation transformers Operations are unique combinations of HTTP paths and methods in an OpenAPI document. Operation transformers are helpful when a modification: @@ -90,7 +86,7 @@ For example, the following operation transformer adds `500` as a response status [!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_operationtransformer1)] -### Use schema transformers +## Use schema transformers Schemas are the data models that are used in request and response bodies in an OpenAPI document. Schema transformers are useful when a modification: @@ -107,6 +103,43 @@ For example, the following schema transformer sets the `format` of decimal types [!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_schematransformer1)] +## Customize schema reuse + +After all transformers have been applied, the framework makes a pass over the document to transfer certain schemas +to the `components.schemas` section, replacing them with `$ref` references to the transferred schema. +This reduces the size of the document and makes it easier to read. + +The details of this processing are complicated and might change in future versions of .NET, but in general: + +* Schemas for class/record/struct types are replaced with a `$ref` to a schema in `components.schemas` + if they appear more than once in the document. +* Schemas for primitive types and standard collections are left inline. +* Schemas for enum types are always replaced with a `$ref` to a schema in components.schemas. + +Typically the name of the schema in `components.schemas` is the name of the class/record/struct type, +but in some circumstances a different name must be used. + +ASP.NET Core lets you customize which schemas are replaced with a `$ref` to a schema in `components.schemas` +using the property of . +This property is a delegate that takes a object and returns the name of the schema +in `components.schemas` that should be used for that type. +The framework provides a default implementation of this delegate, +that uses the name of the type, but you can replace it with your own implementation. + +As a simple example of this customization, you might choose to always inline enum schemas. +This is done by setting to a delegate +that returns null for enum types, and otherwise returns the value from the default implementation. +The following code shows how to do this: + +```csharp +builder.Services.AddOpenApi(options => +{ + // Always inline enum schemas + options.CreateSchemaReferenceId = (type) => + type.Type.IsEnum ? null : OpenApiOptions.CreateDefaultSchemaReferenceId(type); +}); +``` + ## Additional resources * diff --git a/aspnetcore/fundamentals/openapi/include-metadata.md b/aspnetcore/fundamentals/openapi/include-metadata.md index 185d7f4f3911..faa45f434822 100644 --- a/aspnetcore/fundamentals/openapi/include-metadata.md +++ b/aspnetcore/fundamentals/openapi/include-metadata.md @@ -489,8 +489,8 @@ The following table summarizes attributes from the `System.ComponentModel` names | [`[Required]`](xref:System.ComponentModel.DataAnnotations.RequiredAttribute) | Marks a property as `required` in the schema. | | [`[DefaultValue]`](xref:System.ComponentModel.DefaultValueAttribute) | Sets the `default` value of a property in the schema. | | [`[Range]`](xref:System.ComponentModel.DataAnnotations.RangeAttribute) | Sets the `minimum` and `maximum` value of an integer or number. | -| [`[MinLength]`](xref:System.ComponentModel.DataAnnotations.MinLengthAttribute) | Sets the `minLength` of a string. | -| [`[MaxLength]`](xref:System.ComponentModel.DataAnnotations.MaxLengthAttribute) | Sets the `maxLength` of a string. | +| [`[MinLength]`](xref:System.ComponentModel.DataAnnotations.MinLengthAttribute) | Sets the `minLength` of a string or `minItems` of an array. | +| [`[MaxLength]`](xref:System.ComponentModel.DataAnnotations.MaxLengthAttribute) | Sets the `maxLength` of a string or `maxItems` of an array. | | [`[RegularExpression]`](xref:System.ComponentModel.DataAnnotations.RegularExpressionAttribute) | Sets the `pattern` of a string. | Note that in controller-based apps, these attributes add filters to the operation to validate that any incoming data satisfies the constraints. In Minimal APIs, these attributes set the metadata in the generated schema but validation must be performed explicitly via an endpoint filter, in the route handler's logic, or via a third-party package. From b34d8883b0bba028c26e68609b27b8c05bb7d772 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Fri, 17 Jan 2025 07:29:27 -0500 Subject: [PATCH 3/3] Minor script tag guidance language change (#34517) --- .../javascript-interoperability/location-of-javascript.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/blazor/javascript-interoperability/location-of-javascript.md b/aspnetcore/blazor/javascript-interoperability/location-of-javascript.md index b0e6daa754e6..3ac05bba5f36 100644 --- a/aspnetcore/blazor/javascript-interoperability/location-of-javascript.md +++ b/aspnetcore/blazor/javascript-interoperability/location-of-javascript.md @@ -39,7 +39,7 @@ Inline JavaScript isn't recommended for Blazor apps. We recommend using [JS coll :::moniker range=">= aspnetcore-8.0" -Only place a `