diff --git a/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md b/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md index 41a8f726c6be..707fab043e1a 100644 --- a/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md +++ b/aspnetcore/blazor/javascript-interoperability/call-dotnet-from-javascript.md @@ -1169,14 +1169,14 @@ In the preceding example: ## Component instance .NET method helper class -A helper class can invoke a .NET instance method as an . Helper classes are useful in the following scenarios: +A helper class can invoke a .NET instance method as an . Helper classes are useful in scenarios where using static .NET methods aren't applicable: * When several components of the same type are rendered on the same page. * In server-side apps with multiple users concurrently using the same component. In the following example: -* The component contains several `ListItem1` components, which is a shared component in the app's `Shared` folder. +* The component contains several `ListItem1` components. * Each `ListItem1` component is composed of a message and a button. * When a `ListItem1` component button is selected, that `ListItem1`'s `UpdateMessage` method changes the list item text and hides the button. @@ -1345,7 +1345,7 @@ The assignment of a to a proper * In the component's [`OnAfterRender{Async}` method](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync), a JavaScript (JS) function is invoked with the element reference and the component instance as a . The JS function attaches the to the element in a property. * When an element event is invoked in JS (for example, `onclick`), the element's attached is used to call a .NET method. -Similar to the approach described in the [Component instance .NET method helper class](#component-instance-net-method-helper-class) section, this approach is useful in the following scenarios: +Similar to the approach described in the [Component instance .NET method helper class](#component-instance-net-method-helper-class) section, this approach is useful in scenarios where using static .NET methods aren't applicable: * When several components of the same type are rendered on the same page. * In server-side apps with multiple users concurrently using the same component. diff --git a/aspnetcore/blazor/security/blazor-web-app-with-oidc.md b/aspnetcore/blazor/security/blazor-web-app-with-oidc.md index 640ca1a3f622..5002a4f43a00 100644 --- a/aspnetcore/blazor/security/blazor-web-app-with-oidc.md +++ b/aspnetcore/blazor/security/blazor-web-app-with-oidc.md @@ -234,8 +234,18 @@ For more information on (web) API calls using a service abstractions in Blazor W The `BlazorWebAppOidc.Client` project is the client-side project of the Blazor Web App. +:::moniker range=">= aspnetcore-9.0" + +The client calls `AddAuthenticationStateDeserialization` to deserialize and use the authentication state passed by the server. The authentication state is fixed for the lifetime of the WebAssembly application. + +:::moniker-end + +:::moniker range="< aspnetcore-9.0" + The `PersistentAuthenticationStateProvider` class (`PersistentAuthenticationStateProvider.cs`) is a client-side that determines the user's authentication state by looking for data persisted in the page when it was rendered on the server. The authentication state is fixed for the lifetime of the WebAssembly application. +:::moniker-end + If the user needs to log in or out, a full page reload is required. The sample app only provides a user name and email for display purposes. It doesn't include tokens that authenticate to the server when making subsequent requests, which works separately using a cookie that's included on requests to the server. @@ -506,8 +516,18 @@ For more information on (web) API calls using a service abstractions in Blazor W The `BlazorWebAppOidc.Client` project is the client-side project of the Blazor Web App. +:::moniker range=">= aspnetcore-9.0" + +The client calls `AddAuthenticationStateDeserialization` to deserialize and use the authentication state passed by the server. The authentication state is fixed for the lifetime of the WebAssembly application. + +:::moniker-end + +:::moniker range="< aspnetcore-9.0" + The `PersistentAuthenticationStateProvider` class (`PersistentAuthenticationStateProvider.cs`) is a client-side that determines the user's authentication state by looking for data persisted in the page when it was rendered on the server. The authentication state is fixed for the lifetime of the WebAssembly application. +:::moniker-end + If the user needs to log in or out, a full page reload is required. The sample app only provides a user name and email for display purposes. It doesn't include tokens that authenticate to the server when making subsequent requests, which works separately using a cookie that's included on requests to the server. diff --git a/aspnetcore/blazor/security/index.md b/aspnetcore/blazor/security/index.md index a01b4e5eb099..c58646d9c36c 100644 --- a/aspnetcore/blazor/security/index.md +++ b/aspnetcore/blazor/security/index.md @@ -70,7 +70,7 @@ For Microsoft Azure services, we recommend using *managed identities*. Managed i The Blazor template: * Adds antiforgery services automatically when is called in the `Program` file. -* Adds Antiforgery Middleware by calling in its request processing pipeline in the `Program` file and requires endpoint [antiforgery protection](xref:security/anti-request-forgery) to mitigate the threats of Cross-Site Request Forgery (CSRF/XSRF). is called after the call to . If there are calls to and , the call to must go between them. A call to must be placed after calls to and . +* Adds Antiforgery Middleware by calling in its request processing pipeline in the `Program` file and requires endpoint [antiforgery protection](xref:security/anti-request-forgery) to mitigate the threats of Cross-Site Request Forgery (CSRF/XSRF). is called after . A call to must be placed after calls, if present, to and . The component renders an antiforgery token as a hidden field, and this component is automatically added to form () instances. For more information, see . diff --git a/aspnetcore/fundamentals/localization.md b/aspnetcore/fundamentals/localization.md index 8a8699816e41..13be4700eeed 100644 --- a/aspnetcore/fundamentals/localization.md +++ b/aspnetcore/fundamentals/localization.md @@ -13,7 +13,7 @@ uid: fundamentals/localization :::moniker range="> aspnetcore-5.0" -By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://twitter.com/damien_bod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) +By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://github.com/damienbod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) A multilingual website allows a website to reach a wider audience. ASP.NET Core provides services and middleware for localizing into different languages and cultures. diff --git a/aspnetcore/fundamentals/localization/includes/localization35.md b/aspnetcore/fundamentals/localization/includes/localization35.md index c83b3b6a1ce8..e94ee2c607f8 100644 --- a/aspnetcore/fundamentals/localization/includes/localization35.md +++ b/aspnetcore/fundamentals/localization/includes/localization35.md @@ -1,6 +1,6 @@ :::moniker range="= aspnetcore-5.0" -By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://twitter.com/damien_bod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) +By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://github.com/damienbod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) A multilingual website allows a website to reach a wider audience. ASP.NET Core provides services and middleware for localizing into different languages and cultures. diff --git a/aspnetcore/fundamentals/localization/includes/make-content-localizable5.md b/aspnetcore/fundamentals/localization/includes/make-content-localizable5.md index c783e228e2a3..cdbd79492dc9 100644 --- a/aspnetcore/fundamentals/localization/includes/make-content-localizable5.md +++ b/aspnetcore/fundamentals/localization/includes/make-content-localizable5.md @@ -1,6 +1,6 @@ :::moniker range="= aspnetcore-5.0" -By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://twitter.com/damien_bod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) +By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://github.com/damienbod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) One task for localizing an app is to wrap localizable content with code that facilitates replacing that content for different cultures. diff --git a/aspnetcore/fundamentals/localization/includes/provide-resources5.md b/aspnetcore/fundamentals/localization/includes/provide-resources5.md index 31924976e8be..3eec0c86859a 100644 --- a/aspnetcore/fundamentals/localization/includes/provide-resources5.md +++ b/aspnetcore/fundamentals/localization/includes/provide-resources5.md @@ -1,6 +1,6 @@ :::moniker range="= aspnetcore-5.0" -By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://twitter.com/damien_bod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) +By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://github.com/damienbod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) One task for localizing an app is to provide localized strings in resource files. This article is about working with resource files. diff --git a/aspnetcore/fundamentals/localization/includes/select-language-culture5.md b/aspnetcore/fundamentals/localization/includes/select-language-culture5.md index 6c993bcf09fc..afc059c1cafa 100644 --- a/aspnetcore/fundamentals/localization/includes/select-language-culture5.md +++ b/aspnetcore/fundamentals/localization/includes/select-language-culture5.md @@ -1,6 +1,6 @@ :::moniker range="= aspnetcore-5.0" -By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://twitter.com/damien_bod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) +By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://github.com/damienbod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) One task for localizing an app is to implement a strategy for selecting the appropriate culture for each response the app returns. diff --git a/aspnetcore/fundamentals/localization/includes/select-language-culture67.md b/aspnetcore/fundamentals/localization/includes/select-language-culture67.md index 1bee79a68e0a..f4a616c9a3e6 100644 --- a/aspnetcore/fundamentals/localization/includes/select-language-culture67.md +++ b/aspnetcore/fundamentals/localization/includes/select-language-culture67.md @@ -1,7 +1,7 @@ :::moniker range="> aspnetcore-5.0 < aspnetcore-8.0" -[Hisham Bin Ateya](https://twitter.com/hishambinateya), [Damien Bowden](https://twitter.com/damien_bod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Rick Anderson](https://twitter.com/RickAndMSFT) +[Hisham Bin Ateya](https://twitter.com/hishambinateya), [Damien Bowden](https://github.com/damienbod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Rick Anderson](https://twitter.com/RickAndMSFT) One task for localizing an app is to implement a strategy for selecting the appropriate culture for each response the app returns. diff --git a/aspnetcore/fundamentals/localization/make-content-localizable.md b/aspnetcore/fundamentals/localization/make-content-localizable.md index 9f026ce4e15c..48eaa8ba225a 100644 --- a/aspnetcore/fundamentals/localization/make-content-localizable.md +++ b/aspnetcore/fundamentals/localization/make-content-localizable.md @@ -13,7 +13,7 @@ uid: fundamentals/localization/make-content-localizable :::moniker range="> aspnetcore-5.0" -By [Hisham Bin Ateya](https://twitter.com/hishambinateya), [Damien Bowden](https://twitter.com/damien_bod), [Bart Calixto](https://twitter.com/bartmax) and [Nadeem Afana](https://afana.me/) +By [Hisham Bin Ateya](https://twitter.com/hishambinateya), [Damien Bowden](https://github.com/damienbod), [Bart Calixto](https://twitter.com/bartmax) and [Nadeem Afana](https://afana.me/) One task for localizing an app is to wrap localizable content with code that facilitates replacing that content for different cultures. diff --git a/aspnetcore/fundamentals/localization/provide-resources.md b/aspnetcore/fundamentals/localization/provide-resources.md index 4563ddf1c6fe..0c7e5188adb3 100644 --- a/aspnetcore/fundamentals/localization/provide-resources.md +++ b/aspnetcore/fundamentals/localization/provide-resources.md @@ -13,7 +13,7 @@ uid: fundamentals/localization/provide-resources :::moniker range="> aspnetcore-5.0" -By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://twitter.com/damien_bod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) +By [Rick Anderson](https://twitter.com/RickAndMSFT), [Damien Bowden](https://github.com/damienbod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Hisham Bin Ateya](https://twitter.com/hishambinateya) One task for localizing an app is to provide localized strings in resource files. This article is about working with resource files. diff --git a/aspnetcore/fundamentals/localization/select-language-culture.md b/aspnetcore/fundamentals/localization/select-language-culture.md index 96bfbfda6818..976a1ae5ac0a 100644 --- a/aspnetcore/fundamentals/localization/select-language-culture.md +++ b/aspnetcore/fundamentals/localization/select-language-culture.md @@ -13,7 +13,7 @@ uid: fundamentals/localization/select-language-culture :::moniker range=">= aspnetcore-8.0" -[Hisham Bin Ateya](https://twitter.com/hishambinateya), [Damien Bowden](https://twitter.com/damien_bod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Rick Anderson](https://twitter.com/RickAndMSFT) +[Hisham Bin Ateya](https://twitter.com/hishambinateya), [Damien Bowden](https://github.com/damienbod), [Bart Calixto](https://twitter.com/bartmax), [Nadeem Afana](https://afana.me/), and [Rick Anderson](https://twitter.com/RickAndMSFT) One task for localizing an app is to implement a strategy for selecting the appropriate culture for each response the app returns. diff --git a/aspnetcore/fundamentals/openapi/aspnetcore-openapi.md b/aspnetcore/fundamentals/openapi/aspnetcore-openapi.md index 5ace430d8c73..06cb11ba6f90 100644 --- a/aspnetcore/fundamentals/openapi/aspnetcore-openapi.md +++ b/aspnetcore/fundamentals/openapi/aspnetcore-openapi.md @@ -79,20 +79,20 @@ ASP.NET collects metadata from the web app's endpoints and uses it to generate a In controller-based apps, metadata is collected from attributes like [`[EndpointDescription]`](xref:Microsoft.AspNetCore.Http.EndpointDescriptionAttribute), [`[HttpPost]`](xref:Microsoft.AspNetCore.Mvc.HttpPostAttribute), and [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute). In minimal APIs, metadata can be collected from attributes, but may also be set by using extension methods -and other strategies, such as returning [`TypedResults`](xref:Microsoft.AspNetCore.Http.TypedResults) from route handlers. +and other strategies, such as returning from route handlers. The following table provides an overview of the metadata collected and the strategies for setting it. | Metadata | Attribute | Extension method | Other strategies | | --- | --- | --- | -| summary | [`[EndpointSummary]`](xref:Microsoft.AspNetCore.Http.EndpointSummaryAttribute) | [`WithSummary`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithSummary%2A) | | -| description | [`[EndpointDescription]`](xref:Microsoft.AspNetCore.Http.EndpointDescriptionAttribute) | [`WithDescription`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithDescription%2A) | | -| tags | [`[Tags]`](xref:Microsoft.AspNetCore.Http.TagsAttribute) | [`WithTags`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithTags%2A) | | -| operationId | [`[EndpointName]`](xref:Microsoft.AspNetCore.Routing.EndpointNameAttribute) | [`WithName`](xref:Microsoft.AspNetCore.Builder.RoutingEndpointConventionBuilderExtensions.WithName%2A) | | +| summary | [`[EndpointSummary]`](xref:Microsoft.AspNetCore.Http.EndpointSummaryAttribute) | | | +| description | [`[EndpointDescription]`](xref:Microsoft.AspNetCore.Http.EndpointDescriptionAttribute) | | | +| tags | [`[Tags]`](xref:Microsoft.AspNetCore.Http.TagsAttribute) | | | +| operationId | [`[EndpointName]`](xref:Microsoft.AspNetCore.Routing.EndpointNameAttribute) | | | | parameters | [`[FromQuery]`](xref:Microsoft.AspNetCore.Mvc.FromQueryAttribute), [`[FromRoute]`](xref:Microsoft.AspNetCore.Mvc.FromRouteAttribute), [`[FromHeader]`](xref:Microsoft.AspNetCore.Mvc.FromHeaderAttribute), [`[FromForm]`](xref:Microsoft.AspNetCore.Mvc.FromFormAttribute) | | | parameter description | [`[EndpointDescription]`](xref:Microsoft.AspNetCore.Http.EndpointDescriptionAttribute) | | | -| requestBody | [`[FromBody]`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) | [`Accepts`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Accepts%2A) | | -| responses | [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute) | [`Produces`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Produces%2A), [`ProducesProblem`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ProducesProblem%2A) | [`TypedResults`](xref:Microsoft.AspNetCore.Http.TypedResults) | -| Excluding endpoints | [`[ExcludeFromDescription]`](xref:Microsoft.AspNetCore.Routing.ExcludeFromDescriptionAttribute), [`[ApiExplorerSettings]`](xref:Microsoft.AspNetCore.Mvc.ApiExplorerSettingsAttribute) | [`ExcludeFromDescription`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ExcludeFromDescription%2A) | | +| requestBody | [`[FromBody]`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) | | | +| responses | [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute) | , | | +| Excluding endpoints | [`[ExcludeFromDescription]`](xref:Microsoft.AspNetCore.Routing.ExcludeFromDescriptionAttribute), [`[ApiExplorerSettings]`](xref:Microsoft.AspNetCore.Mvc.ApiExplorerSettingsAttribute) | | | ASP.NET Core does not collect metadata from XML doc comments. @@ -101,7 +101,7 @@ The following sections demonstrate how to include metadata in an app to customiz #### Summary and description The endpoint summary and description can be set using the [`[EndpointSummary]`](xref:Microsoft.AspNetCore.Http.EndpointSummaryAttribute) and [`[EndpointDescription]`](xref:Microsoft.AspNetCore.Http.EndpointDescriptionAttribute) attributes, -or in minimal APIs, using the [`WithSummary`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithSummary%2A) and [`WithDescription`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithDescription%2A) extension methods. +or in minimal APIs, using the and extension methods. ##### [Minimal APIs](#tab/minimal-apis) @@ -141,7 +141,7 @@ OpenAPI supports specifying tags on each endpoint as a form of categorization. ##### [Minimal APIs](#tab/minimal-apis) -In minimal APIs, tags can be set using either the [`[Tags]`](xref:Microsoft.AspNetCore.Http.TagsAttribute) attribute or the [`WithTags`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.WithTags%2A) extension method. +In minimal APIs, tags can be set using either the [`[Tags]`](xref:Microsoft.AspNetCore.Http.TagsAttribute) attribute or the extension method. The following sample demonstrates the different strategies for setting tags. @@ -176,7 +176,7 @@ OpenAPI supports an operationId on each endpoint as a unique identifier or name ##### [Minimal APIs](#tab/minimal-apis) -In minimal APIs, the operationId can be set using either the [`[EndpointName]`](xref:Microsoft.AspNetCore.Routing.EndpointNameAttribute) attribute or the [`WithName`](xref:Microsoft.AspNetCore.Builder.RoutingEndpointConventionBuilderExtensions.WithName%2A) extension method. +In minimal APIs, the operationId can be set using either the [`[EndpointName]`](xref:Microsoft.AspNetCore.Routing.EndpointNameAttribute) attribute or the extension method. The following sample demonstrates the different strategies for setting the operationId. @@ -235,37 +235,97 @@ The following sample demonstrates how to set a description for a parameter. ``` --- -#### requestBody +#### Describe the request body - +The `requestBody` field in OpenAPI describes the body of a request that an API client can send to the server, including the content type(s) supported and the schema for the body content. -To define the type of inputs transmitted as the request body, configure the properties by using the [`Accepts`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Accepts%2A) extension method to define the object type and content type that are expected by the request handler. In the following example, the endpoint accepts a `Todo` object in the request body with an expected content-type of `application/xml`. +When the endpoint handler method accepts parameters that are bound from the request body, ASP.NET Core generates a corresponding `requestBody` for the operation in the OpenAPI document. Metadata for the request body can also be specified using attributes or extension methods. Additional metadata can be set with a [document transformer](#use-document-transformers) or [operation transformer](#use-operation-transformers). -```csharp -app.MapPost("/todos/{id}", (int id, Todo todo) => ...) - .Accepts("application/xml"); -``` +If the endpoint doesn't define any parameters bound to the request body, but instead consumes the request body from the directly, ASP.NET Core provides mechanisms to specify request body metadata. This is a common scenario for endpoints that process the request body as a stream. + +Some request body metadata can be determined from the [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) or [`FromForm`](xref:Microsoft.AspNetCore.Mvc.FromFormAttribute) parameters of the route handler method. + +A description for the request body can be set with a [`[Description]`](xref:System.ComponentModel.DescriptionAttribute) attribute on the parameter with [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) or [`FromForm`](xref:Microsoft.AspNetCore.Mvc.FromFormAttribute). + +If the [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) parameter is non-nullable and is not set to in the [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) attribute, the request body is required and the `required` field of the `requestBody` is set to `true` in the generated OpenAPI document. +Form bodies are always required and have `required` set to `true`. + +Use a [document transformer](#use-document-transformers) or an [operation transformer](#use-operation-transformers) to set the `example`, `examples`, or `encoding` fields, or to add specification extensions for the request body in the generated OpenAPI document. + +Other mechanisms for setting request body metadata depend on the type of app being developed and are described in the following sections. + +##### [Minimal APIs](#tab/minimal-apis) + +The content types for the request body in the generated OpenAPI document are determined from the type of the parameter that is bound to the request body or specified with the extension method. +By default, the content type of a [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) parameter will be `application/json` and the content type for [`FromForm`](xref:Microsoft.AspNetCore.Mvc.FromFormAttribute) parameter(s) will be `multipart/form-data` or `application/x-www-form-urlencoded`. - +Support for these default content types is built in to Minimal APIs, and other content types can be handled by using custom binding. +See the [Custom binding](xref:fundamentals/minimal-apis/parameter-binding#custom-binding) topic of the Minimal APIs documentation for more information. -In addition to the [`Accepts`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Accepts%2A) extension method, a parameter type can describe its own annotation by implementing the [`IEndpointParameterMetadataProvider`](xref:Microsoft.AspNetCore.Http.Metadata.IEndpointParameterMetadataProvider) interface. For example, the following `Todo` type adds an annotation that requires a request body with an `application/xml` content-type. +There are several ways to specify a different content type for the request body. +If the type of the [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) parameter implements , ASP.NET Core uses this interface to determine the content type(s) in the request body. +The framework uses the method of this interface to set the content type(s) and type of the body content of the request body. For example, a `Todo` class that accepts either `application/xml` or `text/xml` content-type can use to provide this information to the framework. ```csharp public class Todo : IEndpointParameterMetadataProvider { public static void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder) { - builder.Metadata.Add(new AcceptsMetadata(["application/xml", "text/xml"], typeof(XmlBody))); + builder.Metadata.Add(new AcceptsMetadata(["application/xml", "text/xml"], typeof(Todo))); } } ``` -When no explicit annotation is provided, the framework attempts to determine the default request type if there's a request body parameter in the endpoint handler. The inference uses the following heuristics to produce the annotation: +The extension method can also be used to specify the content type of the request body. +In the following example, the endpoint accepts a `Todo` object in the request body with an expected content-type of `application/xml`. + +```csharp +app.MapPut("/todos/{id}", (int id, Todo todo) => ...) + .Accepts("application/xml"); +``` + +Since `application/xml` is not a built-in content type, the `Todo` class must implement the interface to provide a custom binding for the request body. For example: + +```csharp +public class Todo : IBindableFromHttpContext +{ + public static async ValueTask BindAsync(HttpContext context, ParameterInfo parameter) + { + var xmlDoc = await XDocument.LoadAsync(context.Request.Body, LoadOptions.None, context.RequestAborted); + var serializer = new XmlSerializer(typeof(Todo)); + return (Todo?)serializer.Deserialize(xmlDoc.CreateReader()); + } +``` + +If the endpoint doesn't define any parameters bound to the request body, use the extension method to specify the content type that the endpoint accepts. + +If you specify multiple times, only metadata from the last one is used -- they aren't combined. + +##### [Controllers](#tab/controllers) + +In controller-based apps, the content type(s) for the request body in the generated OpenAPI document are determined from the type of the parameter that is bound to the request body, the types configured in the application, or by a [`[Consumes]`](xref:Microsoft.AspNetCore.Mvc.ConsumesAttribute) attribute on the route handler method. -* Request body parameters that are read from a form via the [`[FromForm]`](xref:Microsoft.AspNetCore.Mvc.FromFormAttribute) attribute are described with the `multipart/form-data` content-type. -* All other request body parameters are described with the `application/json` content-type. -* The request body is treated as optional if it's nullable or if the [`AllowEmpty`](xref:Microsoft.AspNetCore.Http.Metadata.IFromBodyMetadata.AllowEmpty) property is set on the [`[FromBody]`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) attribute. +ASP.NET Core uses an to deserialize a [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) request body. +InputFormatters are configured in the passed to the extension method for the app's service collection. +Each input formatter declares the content types it can handle, in its property, and the type(s) of body content it can handle, with its method. + +ASP.NET Core MVC includes built-in input formatters for JSON and XML, though only the JSON input formatter is enabled by default. +The built-in JSON input formatter supports the `application/json`, `text/json`, and `application/*+json` content types, and the built-in XML input formatter supports the `application/xml`, `text/xml`, and `application/*+xml` content types. + +By default, the content type of a [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) request body may be any content type accepted by an for the [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) parameter type. For a request body with [`FromForm`](xref:Microsoft.AspNetCore.Mvc.FromFormAttribute) parameter(s) the default content types are `multipart/form-data` or `application/x-www-form-urlencoded`.These content types will be included in the generated OpenAPI document if the [`[Consumes]`](xref:Microsoft.AspNetCore.Mvc.ConsumesAttribute) attribute is not specified on the route handler method. + +The content type(s) accepted by a route handler can be restricted using a [filter](xref:mvc/controllers/filters) on the endpoint (action scope). +The [`[Consumes]`](xref:Microsoft.AspNetCore.Mvc.ConsumesAttribute) attribute adds an action scope filter to the endpoint that restricts the content types that a route handler will accept. +In this case, the requestBody in the generated OpenAPI document will include only the content type(s) specified in the [`[Consumes]`](xref:Microsoft.AspNetCore.Mvc.ConsumesAttribute) attribute. + +A [`[Consumes]`](xref:Microsoft.AspNetCore.Mvc.ConsumesAttribute) attribute can't add support for a content type that doesn't have an associated input formatter, and the generated OpenAPI document doesn't include any content types that don't have an associated input formatter. + +For content types other than JSON or XML, you need to create a custom input formatter. +For more information and examples, see [Custom formatters in ASP.NET Core Web API](xref:web-api/advanced/custom-formatters). + +If the route handler doesn't have a [`FromBody`](xref:Microsoft.AspNetCore.Mvc.FromBodyAttribute) or [`FromForm`](xref:Microsoft.AspNetCore.Mvc.FromFormAttribute) parameter, the route handler might read the request body directly from the `Request.Body` stream and might use the [`[Consumes]`](xref:Microsoft.AspNetCore.Mvc.ConsumesAttribute) attribute to restrict the content types allowed, but no requestBody is generated in the OpenAPI document. + +--- #### Describe response types @@ -277,21 +337,21 @@ The specific mechanisms for setting response metadata depend on the type of app In Minimal API apps, ASP.NET Core can extract the response metadata added by extension methods on the endpoint, attributes on the route handler, and the return type of the route handler. -* The [`Produces`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Produces%2A) extension method can be used on the endpoint to specify the status code, the type of the response body, and content type(s) of a response from an endpoint. -* The [`[ProducesResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute) or [`ProducesResponseTypeAttribute`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute%601) attribute can be used to specify the type of the response body. -* A route handler can be used to return a type that implements [`IEndpointMetadataProvider`](xref:Microsoft.AspNetCore.Http.Metadata.IEndpointMetadataProvider) to specify the type and content-type(s) of the response body. -* The [`ProducesProblem`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ProducesProblem%2A) extension method on the endpoint can be used to specify the status code and content-type(s) of an error response. +* The extension method can be used on the endpoint to specify the status code, the type of the response body, and content type(s) of a response from an endpoint. +* The [`[ProducesResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute) or attribute can be used to specify the type of the response body. +* A route handler can be used to return a type that implements to specify the type and content-type(s) of the response body. +* The extension method on the endpoint can be used to specify the status code and content-type(s) of an error response. -Note that the [`Produces`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Produces%2A) and [`ProducesProblem`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ProducesProblem%2A) extension methods are supported on both [`RouteHandlerBuilder`](xref:Microsoft.AspNetCore.Builder.RouteHandlerBuilder) and on [`RouteGroupBuilder`](xref:Microsoft.AspNetCore.Routing.RouteGroupBuilder). This allows, for example, a common set of error responses to be defined for all operations in a group. +Note that the and extension methods are supported on both and on . This allows, for example, a common set of error responses to be defined for all operations in a group. When not specified by one of the preceding strategies, the: * Status code for the response defaults to 200. -* Schema for the response body can be inferred from the implicit or explicit return type of the endpoint method, for example, from `T` in [`Task`](xref:System.Threading.Tasks.Task%601); otherwise, it's considered to be unspecified. +* Schema for the response body can be inferred from the implicit or explicit return type of the endpoint method, for example, from `T` in ; otherwise, it's considered to be unspecified. * Content-type for the specified or inferred response body is "application/json". -In Minimal APIs, the [`Produces`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Produces%2A) extension method and the [`[ProducesResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute) attribute only set the response metadata for the endpoint. They do not modify or constrain the behavior of the endpoint, which may return a different status code or response body type than specified by the metadata, and the content-type is determined by the return type of the route handler method, irrespective of any content-type specified in attributes or extension methods. +In Minimal APIs, the extension method and the [`[ProducesResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute) attribute only set the response metadata for the endpoint. They do not modify or constrain the behavior of the endpoint, which may return a different status code or response body type than specified by the metadata, and the content-type is determined by the return type of the route handler method, irrespective of any content-type specified in attributes or extension methods. -The [`Produces`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Produces%2A) extension method can specify an endpoint's response type, with a default status code of 200 and a default content type of `application/json`. The following example illustrates this: +The extension method can specify an endpoint's response type, with a default status code of 200 and a default content type of `application/json`. The following example illustrates this: ```csharp app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync()) @@ -306,7 +366,7 @@ app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync()); ``` -Using [`TypedResults`](xref:Microsoft.AspNetCore.Http.TypedResults) in the implementation of an endpoint's route handler automatically includes the response type metadata for the endpoint. For example, the following code automatically annotates the endpoint with a response under the `200` status code with an `application/json` content type. +Using in the implementation of an endpoint's route handler automatically includes the response type metadata for the endpoint. For example, the following code automatically annotates the endpoint with a response under the `200` status code with an `application/json` content type. ```csharp app.MapGet("/todos", async (TodoDb db) => @@ -316,7 +376,7 @@ app.MapGet("/todos", async (TodoDb db) => }); ``` -Only return types that implement [`IEndpointMetadataProvider`](xref:Microsoft.AspNetCore.Http.Metadata.IEndpointMetadataProvider) create a `responses` entry in the OpenAPI document. The following is a partial list of some of the [`TypedResults`](xref:Microsoft.AspNetCore.Http.TypedResults) helper methods that produce a `responses` entry: +Only return types that implement create a `responses` entry in the OpenAPI document. The following is a partial list of some of the helper methods that produce a `responses` entry: | TypedResults helper method | status code | | -------------------------- | ----------- | @@ -340,9 +400,9 @@ A class can be implemented to set the endpoint metadata and return it from the r When setting the response type for endpoints that may return a ProblemDetails response, the following can be used to add the appropriate response metadata for the endpoint: -* [`ProducesProblem`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ProducesProblem%2A) -* [`ProducesValidationProblem`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ProducesValidationProblem%2A) extension method. -* [`TypedResults`](xref:Microsoft.AspNetCore.Http.TypedResults) with a status code in the (400-499) range. +* +* extension method. +* with a status code in the (400-499) range. For more information on how to configure a Minimal API app to return ProblemDetails responses, see . @@ -350,15 +410,15 @@ For more information on how to configure a Minimal API app to return ProblemDeta If an endpoint can return different response types in different scenarios, you can provide metadata in the following ways: -* Call the [`Produces`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Produces%2A) extension method multiple times, as shown in the following example: +* Call the extension method multiple times, as shown in the following example: [!code-csharp[](~/fundamentals/minimal-apis/samples/todo/Program.cs?name=snippet_getCustom)] -* Use [`Results`](xref:Microsoft.AspNetCore.Http.HttpResults.Results%606) in the signature and [`TypedResults`](xref:Microsoft.AspNetCore.Http.TypedResults) in the body of the handler, as shown in the following example: +* Use in the signature and in the body of the handler, as shown in the following example: :::code language="csharp" source="~/../AspNetCore.Docs.Samples/fundamentals/minimal-apis/samples/MultipleResultTypes/Program.cs" id="snippet_multiple_result_types"::: - The `Results` [union types](https://en.wikipedia.org/wiki/Union_type) declare that a route handler returns multiple `IResult`-implementing concrete types, and any of those types that implement [`IEndpointMetadataProvider`](xref:Microsoft.AspNetCore.Http.Metadata.IEndpointMetadataProvider) will contribute to the endpoint’s metadata. + The `Results` [union types](https://en.wikipedia.org/wiki/Union_type) declare that a route handler returns multiple `IResult`-implementing concrete types, and any of those types that implement will contribute to the endpoint’s metadata. The union types implement implicit cast operators. These operators enable the compiler to automatically convert the types specified in the generic arguments to an instance of the union type. This capability has the added benefit of providing compile-time checking that a route handler only returns the results that it declares it does. Attempting to return a type that isn't declared as one of the generic arguments to `Results` results in a compilation error. @@ -366,18 +426,18 @@ If an endpoint can return different response types in different scenarios, you c In controller-based apps, ASP.NET Core can extract the response metadata from the action method signature, attributes, and conventions. -* You can use the [`[ProducesResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute) or [`ProducesResponseTypeAttribute`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute%601) attribute to specify the status code, the type of the response body, and content type(s) of a response from an action method. -* You can use the [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute) or [`ProducesAttribute`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute%601) attribute to specify the type of the response body. +* You can use the [`[ProducesResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute) or attribute to specify the status code, the type of the response body, and content type(s) of a response from an action method. +* You can use the [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute) or attribute to specify the type of the response body. * You can use the [`[ProducesDefaultResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute) attribute to specify the response body type for the "default" response. * You can use the [`[ProducesErrorResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesErrorResponseTypeAttribute) attribute to specify the response body type for an error response. However, be aware that this is only complements the status code and content type(s) specified by an [`[ProducesResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute) attribute with a 4XX status code. -Only one [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute) or [`ProducesAttribute`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute%601) attributes may be applied to an action method, but multiple [`[ProducesResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute) or [`ProducesResponseTypeAttribute`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute%601) attributes with different status codes may be applied to a single action method. +Only one [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute) or attributes may be applied to an action method, but multiple [`[ProducesResponseType]`](xref:Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute) or attributes with different status codes may be applied to a single action method. All of the above attributes can be applied to individual action methods or to the controller class where it applies to all action methods in the controller. When not specified by an attribute: * the status code for the response defaults to 200, -* the schema for the response body of 2xx responses may be inferred from the return type of the action method, e.g. from `T` in [`ActionResult`](xref:Microsoft.AspNetCore.Mvc.ActionResult%601), but otherwise is considered to be not specified, +* the schema for the response body of 2xx responses may be inferred from the return type of the action method, e.g. from `T` in , but otherwise is considered to be not specified, * the schema for the response body of 4xx responses is inferred to be a problem details object, * the schema for the response body of 3xx and 5xx responses is considered to be not specified, * the content-type for the response body can be inferred from the return type of the action method and the set of output formatters. @@ -409,7 +469,7 @@ The mechanism for specifying an endpoint that should be excluded depends on the Minimal APIs support two strategies for excluding a given endpoint from the OpenAPI document: -* [`ExcludeFromDescription`](xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.ExcludeFromDescription%2A) extension method +* extension method * [`[ExcludeFromDescription]`](xref:Microsoft.AspNetCore.Routing.ExcludeFromDescriptionAttribute) attribute The following sample demonstrates the different strategies for excluding a given endpoint from the generated OpenAPI document. @@ -443,9 +503,9 @@ The following example demonstrates how to exclude an endpoint from the generated C# classes or records used in request or response bodies are represented as schemas in the generated OpenAPI document. By default, only public properties are represented in the schema, but there are -[`JsonSerializerOptions`](xref:System.Text.Json.JsonSerializerOptions) to also create schema properties for fields. + to also create schema properties for fields. -When the [`PropertyNamingPolicy`](xref:System.Text.Json.JsonSerializerOptions.PropertyNamingPolicy) is set to camel-case (this is the default +When the is set to camel-case (this is the default in ASP.NET web applications), property names in a schema are the camel-case form of the class or record property name. The [`[JsonPropertyName]`](xref:System.Text.Json.Serialization.JsonPropertyNameAttribute) can be used on an individual property to specify the name @@ -506,18 +566,18 @@ Properties can also be marked as `required` with the [required](/dotnet/csharp/l ##### enum -Enum types in C# are integer-based, but can be represented as strings in JSON with a [`[JsonConverter]`](xref:System.Text.Json.Serialization.JsonConverterAttribute) and a [`JsonStringEnumConverter`](xref:System.Text.Json.Serialization.JsonStringEnumConverter). When an enum type is represented as a string in JSON, the generated schema will have an `enum` property with the string values of the enum. +Enum types in C# are integer-based, but can be represented as strings in JSON with a [`[JsonConverter]`](xref:System.Text.Json.Serialization.JsonConverterAttribute) and a . When an enum type is represented as a string in JSON, the generated schema will have an `enum` property with the string values of the enum. An enum type without a [`[JsonConverter]`](xref:System.Text.Json.Serialization.JsonConverterAttribute) will be defined as `type: integer` in the generated schema. **Note:** The [`[AllowedValues]`](xref:System.ComponentModel.DataAnnotations.AllowedValuesAttribute) does not set the `enum` values of a property. ##### nullable -Properties defined as a nullable value or reference type have `nullable: true` in the generated schema. This is consistent with the default behavior of the [`Json`](xref:System.Text.Json) deserializer, which accepts `null` as a valid value for a nullable property. +Properties defined as a nullable value or reference type have `nullable: true` in the generated schema. This is consistent with the default behavior of the deserializer, which accepts `null` as a valid value for a nullable property. ##### additionalProperties -Schemas are generated without an `additionalProperties` assertion by default, which implies the default of `true`. This is consistent with the default behavior of the [`Json`](xref:System.Text.Json) deserializer, which silently ignores additional properties in a JSON object. +Schemas are generated without an `additionalProperties` assertion by default, which implies the default of `true`. This is consistent with the default behavior of the deserializer, which silently ignores additional properties in a JSON object. If the additional properties of a schema should only have values of a specific type, define the property or class as a `Dictionary`. The key type for the dictionary must be `string`. This generates a schema with `additionalProperties` specifying the schema for "type" as the required value types. @@ -573,7 +633,7 @@ builder.Services.AddOpenApi(options => ### Customize the OpenAPI endpoint route -By default, the OpenAPI endpoint registered via a call to [`MapOpenApi`](xref:Microsoft.AspNetCore.Builder.OpenApiEndpointRouteBuilderExtensions.MapOpenApi%2A) exposes the document at the `/openapi/{documentName}.json` endpoint. The following code demonstrates how to customize the route at which the OpenAPI document is registered: +By default, the OpenAPI endpoint registered via a call to exposes the document at the `/openapi/{documentName}.json` endpoint. The following code demonstrates how to customize the route at which the OpenAPI document is registered: ```csharp app.MapOpenApi("/openapi/{documentName}/openapi.json"); @@ -617,17 +677,17 @@ Transformers fall into three categories: * Operation transformers apply to each individual operation. Each individual operation is a combination of path and HTTP method. These can be used to modify parameters or responses on endpoints. * Schema transformers apply to each schema in the document. These can be used to modify the schema of request or response bodies, or any nested schemas. -Transformers can be registered onto the document by calling the [`AddDocumentTransformer`](xref:Microsoft.AspNetCore.OpenApi.OpenApiOptions.AddDocumentTransformer%2A) method on the [`OpenApiOptions`](xref:Microsoft.AspNetCore.OpenApi.OpenApiOptions) object. The following snippet shows different ways to register transformers onto the document: +Transformers can be registered onto the document by calling the method on the object. The following snippet shows different ways to register transformers onto the document: * Register a document transformer using a delegate. -* Register a document transformer using an instance of [`IOpenApiDocumentTransformer`](xref:Microsoft.AspNetCore.OpenApi.IOpenApiDocumentTransformer). -* Register a document transformer using a DI-activated [`IOpenApiDocumentTransformer`](xref:Microsoft.AspNetCore.OpenApi.IOpenApiDocumentTransformer). +* Register a document transformer using an instance of . +* Register a document transformer using a DI-activated . * Register an operation transformer using a delegate. -* Register an operation transformer using an instance of [`IOpenApiOperationTransformer`](xref:Microsoft.AspNetCore.OpenApi.IOpenApiOperationTransformer). -* Register an operation transformer using a DI-activated [`IOpenApiOperationTransformer`](xref:Microsoft.AspNetCore.OpenApi.IOpenApiOperationTransformer). +* Register an operation transformer using an instance of . +* Register an operation transformer using a DI-activated . * Register a schema transformer using a delegate. -* Register a schema transformer using an instance of [`IOpenApiSchemaTransformer`](xref:Microsoft.AspNetCore.OpenApi.IOpenApiSchemaTransformer). -* Register a schema transformer using a DI-activated [`IOpenApiSchemaTransformer`](xref:Microsoft.AspNetCore.OpenApi.IOpenApiSchemaTransformer). +* Register a schema transformer using an instance of . +* Register a schema transformer using a DI-activated . [!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_transUse&highlight=8-19)] @@ -642,14 +702,14 @@ Transformers execute in first-in first-out order based on registration. In the f Document transformers have access to a context object that includes: * The name of the document being modified. -* The [`ApiDescriptionGroups`](xref:Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescriptionGroupCollectionProvider.ApiDescriptionGroups) associated with that document. -* The [`IServiceProvider`](xref:System.IServiceProvider) used in document generation. +* The associated with that document. +* The used in document generation. Document transformers can also mutate the OpenAPI document that is generated. The following example demonstrates a document transformer that adds some information about the API to the OpenAPI document. [!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_documenttransformer1)] -Service-activated document transformers can utilize instances from DI to modify the app. The following sample demonstrates a document transformer that uses the [`IAuthenticationSchemeProvider`](xref:Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider) service from the authentication layer. It checks if any JWT bearer-related schemes are registered in the app and adds them to the OpenAPI document's top level: +Service-activated document transformers can utilize instances from DI to modify the app. The following sample demonstrates a document transformer that uses the service from the authentication layer. It checks if any JWT bearer-related schemes are registered in the app and adds them to the OpenAPI document's top level: [!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_documenttransformer2)] @@ -670,8 +730,8 @@ Operations are unique combinations of HTTP paths and methods in an OpenAPI docum Operation transformers have access to a context object which contains: * The name of the document the operation belongs to. -* The [`ApiDescription`](xref:Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescription) associated with the operation. -* The [`IServiceProvider`](xref:System.IServiceProvider) used in document generation. +* The associated with the operation. +* The used in document generation. For example, the following operation transformer adds `500` as a response status code supported by all operations in the document. @@ -688,7 +748,7 @@ Schema transformers have access to a context object which contains: * The name of the document the schema belongs to. * The JSON type information associated with the target schema. -* The [`IServiceProvider`](xref:System.IServiceProvider) used in document generation. +* The used in document generation. For example, the following schema transformer sets the `format` of decimal types to `decimal` instead of `double`: @@ -703,3 +763,4 @@ For example, the following schema transformer sets the `format` of decimal types [!INCLUDE[](~/fundamentals/openapi/includes/aspnetcore-openapi6-8.md)] + diff --git a/aspnetcore/migration/70-80.md b/aspnetcore/migration/70-80.md index 6ec8f891a67e..22f5d40b63e5 100644 --- a/aspnetcore/migration/70-80.md +++ b/aspnetcore/migration/70-80.md @@ -279,12 +279,20 @@ Blazor Server apps are supported in .NET 8 without any code changes. Use the fol - app.MapFallbackToPage("/_Host"); ``` - Add [Antiforgery Middleware](xref:blazor/security/index#antiforgery-support) to the request processing pipeline after the call to `app.UseRouting`. If there are calls to `app.UseRouting` and `app.UseEndpoints`, the call to `app.UseAntiforgery` must go between them. A call to `app.UseAntiforgery` must be placed after calls to `app.UseAuthentication` and `app.UseAuthorization`. There's no need to add antiforgery services (`builder.Services.AddAntiforgery()`), as they're added automatically by , which was covered earlier. + Remove Routing Middleware: + + ```diff + - app.UseRouting(); + ``` + + Add [Antiforgery Middleware](xref:blazor/security/index#antiforgery-support) to the request processing pipeline after the line that adds HTTPS Redirection Middleware (`app.UseHttpsRedirection`): ```csharp app.UseAntiforgery(); ``` + The preceding call to `app.UseAntiforgery` must be placed after calls, if present, to `app.UseAuthentication` and `app.UseAuthorization`. There's no need to explicitly add antiforgery services (`builder.Services.AddAntiforgery`), as they're added automatically by , which was covered earlier. + 1. If the Blazor Server app was configured to disable prerendering, you can continue to disable prerendering for the updated app. In the `App` component, change the value assigned to the `@rendermode` Razor directive attributes for the and `Routes` components. Change the value of the `@rendermode` directive attribute for both the and `Routes` components to disable prerendering: @@ -427,12 +435,7 @@ Blazor WebAssembly apps are supported in .NET 8 without any code changes. Use th Add [Antiforgery Middleware](xref:blazor/security/index#antiforgery-support) to the request processing pipeline. - Place the following code: - - * After the call to `app.UseRouting`. - * If there are calls to `app.UseRouting` and `app.UseEndpoints`, the call to `app.UseAntiforgery` must go between them. - * The call to `app.UseAntiforgery` must be placed after a call to `app.UseAuthorization`, if present. - * There's no need to add antiforgery services (`builder.Services.AddAntiforgery()`), as they're added automatically by , which was covered earlier. + Place the following line after the call to `app.UseHttpsRedirection`. The call to `app.UseAntiforgery` must be placed after calls, if present, to `app.UseAuthentication` and `app.UseAuthorization`. There's no need to explicitly add antiforgery services (`builder.Services.AddAntiforgery`), as they're added automatically by , which was covered earlier. ```csharp app.UseAntiforgery(); diff --git a/aspnetcore/security/authentication/azure-ad-b2c.md b/aspnetcore/security/authentication/azure-ad-b2c.md index 34cb3c77a49b..a0a05e770682 100644 --- a/aspnetcore/security/authentication/azure-ad-b2c.md +++ b/aspnetcore/security/authentication/azure-ad-b2c.md @@ -9,7 +9,7 @@ uid: security/authentication/azure-ad-b2c --- # Cloud authentication with Azure Active Directory B2C in ASP.NET Core -By [Damien Bod](https://twitter.com/damien_bod) +By [Damien Bod](https://github.com/damienbod) [Azure Active Directory B2C](/azure/active-directory-b2c/active-directory-b2c-overview) (Azure AD B2C) is a cloud identity management solution for web and mobile apps. The service provides authentication for apps hosted in the cloud and on-premises. Authentication types include individual accounts, social network accounts, and federated enterprise accounts. Additionally, Azure AD B2C can provide multi-factor authentication with minimal configuration. diff --git a/aspnetcore/security/enforcing-ssl.md b/aspnetcore/security/enforcing-ssl.md index 229472a3038b..05a863f161ec 100644 --- a/aspnetcore/security/enforcing-ssl.md +++ b/aspnetcore/security/enforcing-ssl.md @@ -5,7 +5,7 @@ description: Learn how to require HTTPS/TLS in an ASP.NET Core web app. ms.author: tdykstra monikerRange: '>= aspnetcore-3.0' ms.custom: mvc, linux-related-content -ms.date: 10/14/2024 +ms.date: 10/24/2024 uid: security/enforcing-ssl --- # Enforce HTTPS in ASP.NET Core diff --git a/aspnetcore/security/enforcing-ssl/includes/enforcing-ssl8.md b/aspnetcore/security/enforcing-ssl/includes/enforcing-ssl8.md index 55c0d815b2f1..d65c959be700 100644 --- a/aspnetcore/security/enforcing-ssl/includes/enforcing-ssl8.md +++ b/aspnetcore/security/enforcing-ssl/includes/enforcing-ssl8.md @@ -225,7 +225,7 @@ Create a policy file (`policies.json`) at: * Windows: `%PROGRAMFILES%\Mozilla Firefox\distribution\` * MacOS: `Firefox.app/Contents/Resources/distribution` -* Linux: See [Trust the certificate with Firefox on Linux](#trust-ff-linux) in this article. +* Linux: See [Trust the certificate with Firefox on Linux](/aspnet/core/security/enforcing-ssl?tabs=visual-studio%2Clinux-ubuntu%2Clinux-sles#trust-the-certificate-with-firefox-on-linux) in this article. Add the following JSON to the Firefox policy file: @@ -324,7 +324,7 @@ For chromium browsers on Linux: * Exit and restart the browser. - + #### Trust the certificate with Firefox on Linux diff --git a/aspnetcore/security/index.md b/aspnetcore/security/index.md index 2b2840462cc4..d8ab5f4c0068 100644 --- a/aspnetcore/security/index.md +++ b/aspnetcore/security/index.md @@ -61,7 +61,7 @@ Managed identities are a secure way to authenticate to services without needing * [Managed identities for App Service and Azure Functions](/azure/app-service/overview-managed-identity) * [Secure authentication flows](/entra/identity-platform/authentication-flows-app-scenarios#web-app-that-signs-in-a-user) -When the app is deployed to a test server, an environment variable can be used to set the connection string to a test database server. For more information, see [Configuration](xref:fundamentals/configuration/index). We recommend environment variables not be used to store a production connection string as it's not the most secure approach. +When the app is deployed to a test server, an environment variable can be used to set the connection string to a test database server. For more information, see [Configuration](xref:fundamentals/configuration/index). Environment variables are generally stored in plain, unencrypted text. If the machine or process is compromised, environment variables can be accessed by untrusted parties. We recommend environment variables not be used to store a production connection string as it's not the most secure approach. For more information, see: diff --git a/aspnetcore/security/ip-safelist.md b/aspnetcore/security/ip-safelist.md index 8841ced09d38..abb38b5ba41b 100644 --- a/aspnetcore/security/ip-safelist.md +++ b/aspnetcore/security/ip-safelist.md @@ -10,7 +10,7 @@ uid: security/ip-safelist --- # Client IP safelist for ASP.NET Core -By [Damien Bowden](https://twitter.com/damien_bod) and [Tom Dykstra](https://github.com/tdykstra) +By [Damien Bowden](https://github.com/damienbod) and [Tom Dykstra](https://github.com/tdykstra) This article shows three ways to implement an IP address safelist (also known as an allow list) in an ASP.NET Core app. An accompanying sample app demonstrates all three approaches. You can use: