diff --git a/aspnetcore/client-side/spa/intro/mermaid/includes/1_BPS.md b/aspnetcore/client-side/spa/intro/mermaid/includes/1_BPS.md deleted file mode 100644 index 42b33c1a9a05..000000000000 --- a/aspnetcore/client-side/spa/intro/mermaid/includes/1_BPS.md +++ /dev/null @@ -1,35 +0,0 @@ -```mermaid -sequenceDiagram -participant Browser -participant Proxy -participant Server -Browser->>Server: GET / -alt Proxy is running - Server->>Browser: 301 Redirect -else Proxy is not running - Server->>Proxy: Launch - par Browser checks with server if the proxy is running - loop Until SPA proxy is running - Server->>Browser: 200 OK ... - Browser->>Browser: Wait - Browser->>Server: GET / - end - and Server checks if proxy is ready - loop Until SPA proxy is ready - Server->>Proxy: GET - alt Proxy not ready - Proxy->>Server: Error - else Proxy ready - Proxy->>Server: 200 OK ... - end - end - end - Server->>Browser: 301 Redirect -end -Browser->>Proxy: GET -Proxy->>Browser: 200 OK ... -loop Other resources and requests - Browser->>Proxy: HTTP Request - Proxy->>Browser: HTTP Response -end -``` \ No newline at end of file diff --git a/aspnetcore/client-side/spa/intro/mermaid/includes/2BP.md b/aspnetcore/client-side/spa/intro/mermaid/includes/2BP.md deleted file mode 100644 index 1894df74b9bd..000000000000 --- a/aspnetcore/client-side/spa/intro/mermaid/includes/2BP.md +++ /dev/null @@ -1,10 +0,0 @@ -```mermaid -sequenceDiagram -participant Browser -participant Proxy -participant Server -Browser->>Proxy: GET /weatherforecast -Proxy->>Server: GET /weatherforecast -Server->>Proxy: 200 OK -Proxy->>Browser: 200 OK -``` \ No newline at end of file diff --git a/aspnetcore/fundamentals/minimal-apis/handle-errors/includes/handle-errors7.md b/aspnetcore/fundamentals/minimal-apis/handle-errors/includes/handle-errors7.md deleted file mode 100644 index e2f9d6e24522..000000000000 --- a/aspnetcore/fundamentals/minimal-apis/handle-errors/includes/handle-errors7.md +++ /dev/null @@ -1,150 +0,0 @@ - :::moniker range="= aspnetcore-7.0" - -This article describes how to handle errors in Minimal API apps. - -## Exceptions - -In a Minimal API app, there are two different built-in centralized mechanisms to handle unhandled exceptions: - -* [Developer Exception Page middleware](#developer-exception-page) (For use in the **`Development` environment only**.) -* [Exception handler middleware](#exception-handler) - -This section refers to the following Minimal API app to demonstrate ways to handle exceptions. It throws an exception when the endpoint `/exception` is requested: - -```csharp -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -app.Map("/exception", () - => { throw new InvalidOperationException("Sample Exception"); }); - -app.Run(); -``` - -### Developer Exception Page - -The [Developer Exception Page](xref:fundamentals/error-handling#developer-exception-page) shows detailed stack traces for server errors. It uses to capture synchronous and asynchronous exceptions from the HTTP pipeline and to generate error responses. - -ASP.NET Core apps enable the developer exception page by default when both: - -* Running in the [`Development` environment](xref:fundamentals/environments). -* App is using [WebApplication.CreateBuilder](/dotnet/api/microsoft.aspnetcore.builder.webapplication.createbuilder). - -For more information on configuring middleware, see [Middleware in ASP.NET Core apps](xref:fundamentals/middleware/index#middleware-added-automatically-by-webapplication). - -Using the preceding Minimal API app, when the `Developer Exception Page` detects an unhandled exception, it generates a default plain-text response similar to the following example: - -```console -HTTP/1.1 500 Internal Server Error -Content-Type: text/plain; charset=utf-8 -Date: Thu, 27 Oct 2022 18:00:59 GMT -Server: Kestrel -Transfer-Encoding: chunked - - System.InvalidOperationException: Sample Exception - at Program.<>c.<
$>b__0_1() in ....:line 17 - at lambda_method2(Closure, Object, HttpContext) - at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) - --- End of stack trace from previous location --- - at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context) -HEADERS -======= -Accept: */* -Connection: keep-alive -Host: localhost:5239 -Accept-Encoding: gzip, deflate, br -``` - -> [!WARNING] -> Don't enable the Developer Exception Page **unless the app is running in the `Development` environment**. Don't share detailed exception information publicly when the app runs in production. For more information on configuring environments, see . - -### Exception handler - -In non-development environments, use the [exception handler middleware](xref:fundamentals/error-handling#exception-handler-page) to produce an error payload. To configure the `exception handler middleware`, call . - -For example, the following code changes the app to respond with an [RFC 7807](https://tools.ietf.org/html/rfc7807)-compliant payload to the client. For more information, see [Problem Details](#problem-details) section. - - -```csharp -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -app.UseExceptionHandler(exceptionHandlerApp - => exceptionHandlerApp.Run(async context - => await Results.Problem() - .ExecuteAsync(context))); - -app.Map("/exception", () - => { throw new InvalidOperationException("Sample Exception"); }); - -app.Run(); -``` - -## Client and Server error responses - -Consider the following Minimal API app. - -```csharp -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -app.Map("/users/{id:int}", (int id) - => id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) ); - -app.Run(); - -public record User(int Id); -``` - -The `/users` endpoint produces `200 OK` with a `json` representation of `User` when `id` is greater than `0`, otherwise a `400 BAD REQUEST` status code without a response body. For more information about creating a response, see [Create responses in Minimal API apps](/aspnet/core/fundamentals/minimal-apis/responses). - -The [`Status Code Pages middleware`](xref:fundamentals/error-handling#sestatuscodepages) can be configured to produce a common body content, **when empty**, for all HTTP client (`400`-`499`) or server (`500` -`599`) responses. The middleware is configured by calling the -[UseStatusCodePages]() extension method. - -For example, the following example changes the app to respond with an [RFC 7807](https://tools.ietf.org/html/rfc7807)-compliant payload to the client for all client and server responses, including routing errors (for example, `404 NOT FOUND`). For more information, see the [Problem Details](#problem-details) section. - -```csharp -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -app.UseStatusCodePages(async statusCodeContext - => await Results.Problem(statusCode: statusCodeContext.HttpContext.Response.StatusCode) - .ExecuteAsync(statusCodeContext.HttpContext)); - -app.Map("/users/{id:int}", (int id) - => id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) ); - -app.Run(); - -public record User(int Id); -``` - -## Problem details - -[!INCLUDE[](~/includes/problem-details-service.md)] - -Minimal API apps can be configured to generate problem details response for all HTTP client and server error responses that ***don't have a body content yet*** by using the `AddProblemDetails` extension method. - -The following code configures the app to generate problem details: - -```csharp -var builder = WebApplication.CreateBuilder(args); -builder.Services.AddProblemDetails(); - -var app = builder.Build(); - -app.UseExceptionHandler(); -app.UseStatusCodePages(); - -app.Map("/users/{id:int}", (int id) - => id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) ); - -app.Map("/exception", () - => { throw new InvalidOperationException("Sample Exception"); }); - -app.Run(); -``` - -For more information on using `AddProblemDetails`, see [Problem Details](/aspnet/core/fundamentals/error-handling?view=aspnetcore-7.0&preserve-view=true#pds7) - -:::moniker-end diff --git a/aspnetcore/includes/combine-service-collection-31-to-60.md b/aspnetcore/includes/combine-service-collection-31-to-60.md deleted file mode 100644 index 8b137891791f..000000000000 --- a/aspnetcore/includes/combine-service-collection-31-to-60.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/aspnetcore/includes/combine-service-collection-60-or-later.md b/aspnetcore/includes/combine-service-collection-60-or-later.md deleted file mode 100644 index 9c1281e82381..000000000000 --- a/aspnetcore/includes/combine-service-collection-60-or-later.md +++ /dev/null @@ -1,71 +0,0 @@ -Consider the following which registers services and configures options: - -```csharp -using ConfigSample.Options; -using Microsoft.Extensions.DependencyInjection.ConfigSample.Options; - -var builder = WebApplication.CreateBuilder(args); - -builder.Services.AddRazorPages(); - -builder.Services.Configure( - builder.Configuration.GetSection(PositionOptions.Position)); -builder.Services.Configure( - builder.Configuration.GetSection(ColorOptions.Color)); - -builder.Services.AddScoped(); -builder.Services.AddScoped(); - -var app = builder.Build(); -``` - -Related groups of registrations can be moved to an extension method to register services. For example, the configuration services are added to the following class: - -```csharp -using ConfigSample.Options; -using Microsoft.Extensions.Configuration; - -namespace Microsoft.Extensions.DependencyInjection -{ - public static class MyConfigServiceCollectionExtensions - { - public static IServiceCollection AddConfig( - this IServiceCollection services, IConfiguration config) - { - services.Configure( - config.GetSection(PositionOptions.Position)); - services.Configure( - config.GetSection(ColorOptions.Color)); - - return services; - } - - public static IServiceCollection AddMyDependencyGroup( - this IServiceCollection services) - { - services.AddScoped(); - services.AddScoped(); - - return services; - } - } -} -``` - -The remaining services are registered in a similar class. The following code uses the new extension methods to register the services: - -```csharp -using Microsoft.Extensions.DependencyInjection.ConfigSample.Options; - -var builder = WebApplication.CreateBuilder(args); - -builder.Services - .AddConfig(builder.Configuration) - .AddMyDependencyGroup(); - -builder.Services.AddRazorPages(); - -var app = builder.Build(); -``` - -**_Note:_** Each `services.Add{GROUP_NAME}` extension method adds and potentially configures services. For example, adds the services MVC controllers with views require, and adds the services Razor Pages requires. diff --git a/aspnetcore/includes/mac-terminal-access.md b/aspnetcore/includes/mac-terminal-access.md deleted file mode 100644 index 91021f9aad45..000000000000 --- a/aspnetcore/includes/mac-terminal-access.md +++ /dev/null @@ -1,14 +0,0 @@ - -### Accessing a Command Terminal on Mac - -Accessing a command terminal on Mac for the first time requires the following setting configurations: - -* Navigate to **System Preferences > Keyboard > Shortcuts > Services**. -* Under **Files and Folders**, verify **New Terminal at Folder** is selected. - -The preceding instructions enable accessing a command terminal two ways: from inside **Visual Studio** or from **Finder**. - -#### To access a command terminal from Finder: - -* Right click the desired folder. -* At the bottom of the list, select **New Terminal at Folder**. diff --git a/aspnetcore/includes/monikerSdks/moniker8-9-10-sdk.md b/aspnetcore/includes/monikerSdks/moniker8-9-10-sdk.md deleted file mode 100644 index be2e8c5aed04..000000000000 --- a/aspnetcore/includes/monikerSdks/moniker8-9-10-sdk.md +++ /dev/null @@ -1,10 +0,0 @@ -:::moniker-end -:::moniker range="= aspnetcore-8.0" -* [!INCLUDE[](~/includes/8.0-SDK.md)] -:::moniker-end -:::moniker range="= aspnetcore-9.0" -* [!INCLUDE[](~/includes/9.0-SDK.md)] -:::moniker-end -:::moniker range=">= aspnetcore-10.0" -* [!INCLUDE[](~/includes/10.0-SDK.md)] -:::moniker-end diff --git a/aspnetcore/includes/not-ga-yet.md b/aspnetcore/includes/not-ga-yet.md deleted file mode 100644 index 7a863e3c8b2b..000000000000 --- a/aspnetcore/includes/not-ga-yet.md +++ /dev/null @@ -1,10 +0,0 @@ -> [!IMPORTANT] -> This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here. - - diff --git a/aspnetcore/includes/preview-notice.md b/aspnetcore/includes/preview-notice.md deleted file mode 100644 index b316528fe12d..000000000000 --- a/aspnetcore/includes/preview-notice.md +++ /dev/null @@ -1,3 +0,0 @@ -> [!IMPORTANT] -> -> This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here. diff --git a/aspnetcore/migration/fx-to-core/inc/includes/mermaid.md b/aspnetcore/migration/fx-to-core/inc/includes/mermaid.md deleted file mode 100644 index ca4212d78984..000000000000 --- a/aspnetcore/migration/fx-to-core/inc/includes/mermaid.md +++ /dev/null @@ -1,82 +0,0 @@ -mermaid incase we want to change images - -```mermaid - sequenceDiagram - participant core as ASP.NET Core - participant framework as ASP.NET - participant session as Session Store - core ->> framework: GET /session - framework ->> session: Request session - session -->> framework: Session - framework -->> core: Session -``` - -## Writeable - -```mermaid - sequenceDiagram - participant core as ASP.NET Core - participant framework as ASP.NET - participant session as Session Store - core ->> framework: GET /session - framework ->> session: Request session - session -->> framework: Session - framework -->> core: Session - core ->> framework: PUT /session - framework ->> framework: Deserialize to HttpSessionState - framework -->> core: Session complete - framework ->> session: Persist -``` - - Windows with its supporting libraries: - -```mermaid -flowchart LR; - external[Incoming requests] --> framework[.NET Framework App] - framework --- libraries[[Business logic]] -``` - - but the core app is now set up to start migrating routes to: did below change? - -```mermaid -flowchart LR; - external[Incoming requests] --> core[ASP.NET Core App] - core --- - --- libraries - core -- YARP proxy --> framework[ \n\n.NET Framework App\n\n\n] - framework --- libraries[[Business logic]] -``` - -In order to start moving over business logic that relies on `HttpContext`, - -```mermaid -flowchart LR; - external[Incoming requests] --> core[ASP.NET Core App] - core -- Adapters --- libraries - core -- YARP proxy --> framework[ \n\n.NET Framework App\n\n\n] - framework --- libraries[[Business logic]] -``` - -Over time, the core app will start processing more of the routes served than the .NET Framework App: - -```mermaid -flowchart LR; - external[Incoming requests] --> core[ \n\nASP.NET Core App\n\n\n] - core -- Adapters --- libraries - core -- YARP proxy --> framework[.NET Framework App] - framework --- libraries[[Business logic]] -``` - -Once the .NET Framework App is no longer needed, it may be removed: - -```mermaid -flowchart LR; - external[Incoming requests] --> core[ASP.NET Core App] - core -- Adapters --- libraries[[Business logic]] -``` - -At this point, the application as a whole is running on the ASP.NET Core application stack, -```mermaid -flowchart LR; - external[Incoming requests] --> core[ASP.NET Core App] - core --- libraries[[Business logic]] -``` diff --git a/aspnetcore/release-notes/aspnetcore-10/includes/OpenApiNetV2Prev7.md b/aspnetcore/release-notes/aspnetcore-10/includes/OpenApiNetV2Prev7.md deleted file mode 100644 index 35a71ddb4d3c..000000000000 --- a/aspnetcore/release-notes/aspnetcore-10/includes/OpenApiNetV2Prev7.md +++ /dev/null @@ -1,6 +0,0 @@ -### Upgrade to OpenAPI.NET v2.0.0-preview7 - -The [OpenAPI.NET](https://github.com/microsoft/OpenAPI.NET) library used in ASP.NET Core OpenAPI document generation has been upgraded to v2.0.0-preview7. This version includes various bug fixes and improvements while also introducing some breaking changes. The breaking changes should only impact users that use document, operation, or schema transformers. Breaking changes in this iteration include the following: - -* Entities within the OpenAPI document, like operations and parameters, are typed as interfaces. Concrete implementations exist for the inlined and referenced variants of an entity. For example, an `IOpenApiSchema` can either be an inlined `OpenApiSchema` or an `OpenApiSchemaReference` that points to a schema defined elsewhere in the document. -* The `Nullable` property has been removed from the `OpenApiSchema` type. To determine if a type is nullable, evaluate if the `OpenApiSchema.Type` property sets `JsonSchemaType.Null`. \ No newline at end of file diff --git a/aspnetcore/release-notes/aspnetcore-11/includes/direct-tls-transport.md b/aspnetcore/release-notes/aspnetcore-11/includes/direct-tls-transport.md deleted file mode 100644 index 7e3344a5b0da..000000000000 --- a/aspnetcore/release-notes/aspnetcore-11/includes/direct-tls-transport.md +++ /dev/null @@ -1,27 +0,0 @@ -### Experimental DirectTls transport - -> [!WARNING] -> `DirectTls` is experimental in .NET 11 and produces diagnostic `ASPNETCORE_DIRECTTLS_001`. - -`DirectTls` is an opt-in Kestrel transport for Linux that terminates TLS directly on the connection's socket by using the runtime's low-level TLS APIs. It binds OpenSSL to the socket file descriptor instead of using , avoiding an intermediate managed copy on the TLS data path. The transport is being explored for connection-dense and handshake-heavy workloads where those copies and allocations can be significant. - -`DirectTls` ships as the standalone `Microsoft.AspNetCore.Server.Kestrel.Transport.DirectTls` package and requires OpenSSL on the host. After adding a reference to the package, call `UseDirectTls()` to register the transport and select it for a specific endpoint. The following example assumes that `certificate` is an loaded from the app's secure certificate configuration: - -```csharp -using System.Net; -using Microsoft.AspNetCore.Server.Kestrel.Core; -using Microsoft.AspNetCore.Server.Kestrel.Transport.DirectTls; - -#pragma warning disable ASPNETCORE_DIRECTTLS_001 // DirectTls is experimental. - -builder.WebHost.UseKestrel(); -builder.WebHost.UseDirectTls(); -builder.WebHost.ConfigureKestrel(options => -{ - var endpoint = new DirectTlsEndpoint(IPAddress.Any, 5001); - endpoint.Options.ServerCertificate = certificate; - options.Listen(endpoint); -}); -``` - -Only endpoints configured with `DirectTlsEndpoint` use DirectTls. Other endpoints continue to use the default sockets transport and the standard Kestrel TLS implementation. diff --git a/aspnetcore/release-notes/aspnetcore-9/includes/newFeature1.md b/aspnetcore/release-notes/aspnetcore-9/includes/newFeature1.md deleted file mode 100644 index 57cd1e68e6cd..000000000000 --- a/aspnetcore/release-notes/aspnetcore-9/includes/newFeature1.md +++ /dev/null @@ -1,6 +0,0 @@ - -To prevent merge conflicts in ~/aspnetcore-9.md, new features should be documented in this include folder. Content in the include folder is not published unless explicitly referenced in a topic. For example: - -[!INCLUDE[](~/release-notes/aspnetcore-9.0.md)] - ---> diff --git a/aspnetcore/release-notes/aspnetcore-9/includes/openAPI_completion.md b/aspnetcore/release-notes/aspnetcore-9/includes/openAPI_completion.md deleted file mode 100644 index 56e11c6911c7..000000000000 --- a/aspnetcore/release-notes/aspnetcore-9/includes/openAPI_completion.md +++ /dev/null @@ -1,128 +0,0 @@ -### Intellisense completion enhancements for OpenAPI package - -ASP.NET Core's OpenAPI support is now more accessible and user-friendly. The OpenAPI APIs are shipped as an independent package, separate from the shared framework. Until now, this meant that developers didn't have the convenience of code-completion features like Intellisense for OpenAPI APIs. - -Recognizing this gap, we have introduced a new completion provider and code fixer. These tools are designed to facilitate the discovery and use of OpenAPI APIs, making it easier for developers to integrate OpenAPI into their projects. The completion provider offers real-time code suggestions, while the code fixer assists in correcting common mistakes and improving API usage. This enhancement is part of our ongoing commitment to improve the developer experience and streamline API-related workflows. - -When a user types a statement where an OpenAPI-related API is available, the completion provider displays a recommendation for the API. For example, in the following screenshots, completions for and are provided when a user is entering an invocation statement on a supported type, such as : - -OpenAPI completions - -When the completion is accepted and the `Microsoft.AspNetCore.OpenApi` package is not installed, a codefixer provides a shortcut for automatically installing the dependency in the project. - -Automatic package installation - -### Support for `[Required]` and `[DefaultValue]` attributes on parameters and properties - -When [`[Required]`](/dotnet/api/system.componentmodel.dataannotations.requiredattribute) and [`[DefaultValue]`](/dotnet/api/system.componentmodel.defaultvalueattribute) attributes are applied on parameters or properties within complex types, the OpenAPI implementation maps these to the `required` and `default` properties in the OpenAPI document associated with the parameter or type schema. - -For example, the following API produces the accompanying schema for the `Todo` type. - -```csharp -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -var builder = WebApplication.CreateBuilder(); - -builder.Services.AddOpenApi(); - -var app = builder.Build(); - -if (app.Environment.IsDevelopment()) -{ - app.MapOpenApi(); -} - -app.MapPost("/todos", (Todo todo) => { }); - -app.Run(); - -class Todo -{ - public int Id { get; init; } - public required string Title { get; init; } - [DefaultValue("A new todo")] - public required string Description { get; init; } - [Required] - public DateTime CreatedOn { get; init; } -} -``` - -```json -{ - "required": [ - "title", - "description", - "createdOn" - ], - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int32" - }, - "title": { - "type": "string" - }, - "description": { - "type": "string", - "default": "A new todo" - }, - "createdOn": { - "type": "string", - "format": "date-time" - } - } -} -``` - -### Support for schema transformers on OpenAPI documents - -Built-in OpenAPI support now ships with support for schema transformers that can be used to modify schemas generated by and the OpenAPI implementation. Like document and operation transformers, schema transformers can be registered on the object. For example, the following code sample demonstrates using a schema transformer to add an example to a type's schema. - -```csharp -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using Microsoft.OpenApi.Any; - -var builder = WebApplication.CreateBuilder(); - -builder.Services.AddOpenApi(options => -{ - options.AddSchemaTransformer((schema, context, cancellationToken) => - { - if (context.JsonTypeInfo.Type == typeof(Todo)) - { - schema.Example = new OpenApiObject - { - ["id"] = new OpenApiInteger(1), - ["title"] = new OpenApiString("A short title"), - ["description"] = new OpenApiString("A long description"), - ["createdOn"] = new OpenApiDateTime(DateTime.Now) - }; - } - return Task.CompletedTask; - }); -}); - -var app = builder.Build(); - -if (app.Environment.IsDevelopment()) -{ - app.MapOpenApi(); -} - -app.MapPost("/todos", (Todo todo) => { }); - -app.Run(); - -class Todo -{ - public int Id { get; init; } - public required string Title { get; init; } - [DefaultValue("A new todo")] - public required string Description { get; init; } - [Required] - public DateTime CreatedOn { get; init; } -} -``` diff --git a/aspnetcore/security/authentication/includes/mike-auth-powertags.md b/aspnetcore/security/authentication/includes/mike-auth-powertags.md deleted file mode 100644 index 584e5fdd54eb..000000000000 --- a/aspnetcore/security/authentication/includes/mike-auth-powertags.md +++ /dev/null @@ -1,3 +0,0 @@ -# A comprehensive overview of authentication in ASP.NET Core – for fellow developers who're struggling with authentication in .NET - -Replace with contents of A comprehensive overview of authentication in ASP.NET Core – for fellow developers who're struggling with authentication in .NET diff --git a/aspnetcore/security/authentication/social/includes/default-settings2-2.md b/aspnetcore/security/authentication/social/includes/default-settings2-2.md deleted file mode 100644 index 1898a1bc2694..000000000000 --- a/aspnetcore/security/authentication/social/includes/default-settings2-2.md +++ /dev/null @@ -1,3 +0,0 @@ -The call to configures the default scheme settings. The overload sets the property. The overload allows configuring authentication options, which can be used to set up default authentication schemes for different purposes. Subsequent calls to `AddAuthentication` override previously configured properties. - - extension methods that register an authentication handler may only be called once per authentication scheme. Overloads exist that allow configuring the scheme properties, scheme name, and display name. diff --git a/aspnetcore/security/includes/choose-identity-diagram.md b/aspnetcore/security/includes/choose-identity-diagram.md deleted file mode 100644 index 1054794b430d..000000000000 --- a/aspnetcore/security/includes/choose-identity-diagram.md +++ /dev/null @@ -1,14 +0,0 @@ -```mermaid -graph LR - A(What identity solution is right for me?) --> B{Do external apps access your protected APIs?} - B --> |Yes| C{Does your app have Internet access all the time?} - B --> |No| D{Does your app need to support single sign on?} - C --> |Yes| E{Are you required to store user data on your servers?} - C --> |No| F(Self host, installed or container-based, OIDC server) - D --> |Yes| C - D --> |No| G{Does your app have a mobile or desktop client?} - E --> |Yes| F - E --> |No| H(Cloud or managed OIDC server) - G --> |Yes| I(Cookie-based identity is preferred over token-based identity, mobile or desktop, using ASP.NET Core Identity) - G --> |No| J(Cookie-based identity, web, using ASP.NET Core Identity) -``` diff --git a/aspnetcore/signalr/redis-backplane/includes/redis-backplane.md b/aspnetcore/signalr/redis-backplane/includes/redis-backplane.md deleted file mode 100644 index e228b5170ee7..000000000000 --- a/aspnetcore/signalr/redis-backplane/includes/redis-backplane.md +++ /dev/null @@ -1,225 +0,0 @@ -:::moniker range="> aspnetcore-2.0 <= aspnetcore-5.0" - - -This article explains SignalR-specific aspects of setting up a [Redis](https://redis.io/) server to use for scaling out an ASP.NET Core SignalR app. - -[!INCLUDE [managed-identities](~/includes/managed-identities-conn-strings.md)] - -## Set up a Redis backplane - -* Deploy a Redis server. - - > [!IMPORTANT] - > For production use, a Redis backplane is recommended only when it runs in the same data center as the SignalR app. Otherwise, network latency degrades performance. If your SignalR app is running in the Azure cloud, we recommend Azure SignalR Service instead of a Redis backplane. - - For more information, see the following resources: - - * - * [Redis documentation](https://redis.io/) - * [Azure Redis Cache documentation](/azure/azure-cache-for-redis/) - -:::moniker range="= aspnetcore-2.1" - -* In the SignalR app, install the `Microsoft.AspNetCore.SignalR.Redis` NuGet package. -* In the `Startup.ConfigureServices` method, call `AddRedis` after `AddSignalR`: - - ```csharp - services.AddSignalR().AddRedis(""); - ``` - -* Configure options as needed: - - Most options can be set in the connection string or in the [ConfigurationOptions](https://stackexchange.github.io/StackExchange.Redis/Configuration#configuration-options) object. Options specified in `ConfigurationOptions` override the ones set in the connection string. - - The following example shows how to set options in the `ConfigurationOptions` object. This example adds a channel prefix so that multiple apps can share the same Redis instance, as explained in the following step. - - ```csharp - services.AddSignalR() - .AddRedis(connectionString, options => { - options.Configuration.ChannelPrefix = "MyApp"; - }); - ``` - - In the preceding code, `options.Configuration` is initialized with whatever was specified in the connection string. - -:::moniker-end - -:::moniker range="= aspnetcore-2.2" - -* In the SignalR app, install one of the following NuGet packages: - - * `Microsoft.AspNetCore.SignalR.StackExchangeRedis` - Depends on StackExchange.Redis 2.X.X. This is the recommended package for ASP.NET Core 2.2 or later. - * `Microsoft.AspNetCore.SignalR.Redis` - Depends on StackExchange.Redis 1.X.X. This package isn't included in ASP.NET Core 3.0 or later. - -* In the `Startup.ConfigureServices` method, call : - - ```csharp - services.AddSignalR().AddStackExchangeRedis(""); - ``` - - When using `Microsoft.AspNetCore.SignalR.Redis`, call . - -* Configure options as needed: - - Most options can be set in the connection string or in the [ConfigurationOptions](https://stackexchange.github.io/StackExchange.Redis/Configuration#configuration-options) object. Options specified in `ConfigurationOptions` override the ones set in the connection string. - - The following example shows how to set options in the `ConfigurationOptions` object. This example adds a channel prefix so that multiple apps can share the same Redis instance, as explained in the following step. - - ```csharp - services.AddSignalR() - .AddStackExchangeRedis(connectionString, options => { - options.Configuration.ChannelPrefix = "MyApp"; - }); - ``` - - When using `Microsoft.AspNetCore.SignalR.Redis`, call . - - In the preceding code, `options.Configuration` is initialized with whatever was specified in the connection string. - - For information about Redis options, see the [StackExchange Redis documentation](https://stackexchange.github.io/StackExchange.Redis/Configuration.html). - -:::moniker-end - -:::moniker range=">= aspnetcore-3.0" - -* In the SignalR app, install the following NuGet package: - - * `Microsoft.AspNetCore.SignalR.StackExchangeRedis` - -* In the `Startup.ConfigureServices` method, call : - - ```csharp - services.AddSignalR().AddStackExchangeRedis(""); - ``` - -* Configure options as needed: - - Most options can be set in the connection string or in the [`ConfigurationOptions`](https://stackexchange.github.io/StackExchange.Redis/Configuration#configuration-options) object. Options specified in `ConfigurationOptions` override the ones set in the connection string. - - The following example shows how to set options in the `ConfigurationOptions` object. This example adds a channel prefix so that multiple apps can share the same Redis instance, as explained in the following step. - - ```csharp - services.AddSignalR() - .AddStackExchangeRedis(connectionString, options => { - options.Configuration.ChannelPrefix = "MyApp"; - }); - ``` - - In the preceding code, `options.Configuration` is initialized with whatever was specified in the connection string. - - For information about Redis options, see the [StackExchange Redis documentation](https://stackexchange.github.io/StackExchange.Redis/Configuration.html). - -:::moniker-end - -* If you're using one Redis server for multiple SignalR apps, use a different channel prefix for each SignalR app. - - Setting a channel prefix isolates one SignalR app from others that use different channel prefixes. If you don't assign different prefixes, a message sent from one app to all of its own clients will go to all clients of all apps that use the Redis server as a backplane. - -* Configure your server farm load balancing software for sticky sessions. Here are some examples of documentation on how to do that: - - * [IIS](/iis/extensions/configuring-application-request-routing-arr/http-load-balancing-using-application-request-routing) - * [HAProxy](https://www.haproxy.com/blog/load-balancing-affinity-persistence-sticky-sessions-what-you-need-to-know/) - * [Nginx](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/#sticky) - -## Redis server errors - -When a Redis server goes down, SignalR throws exceptions that indicate messages won't be delivered. Some typical exception messages: - -* *Failed writing message* -* *Failed to invoke hub method 'MethodName'* -* *Connection to Redis failed* - -SignalR doesn't buffer messages to send them when the server comes back up. Any messages sent while the Redis server is down are lost. - -SignalR automatically reconnects when the Redis server is available again. - -### Custom behavior for connection failures - -Here's an example that shows how to handle Redis connection failure events. - -:::moniker range="= aspnetcore-2.1" - -```csharp -services.AddSignalR() - .AddRedis(o => - { - o.ConnectionFactory = async writer => - { - var config = new ConfigurationOptions - { - AbortOnConnectFail = false - }; - config.EndPoints.Add(IPAddress.Loopback, 0); - config.SetDefaultPorts(); - var connection = await ConnectionMultiplexer.ConnectAsync(config, writer); - connection.ConnectionFailed += (_, e) => - { - Console.WriteLine("Connection to Redis failed."); - }; - - if (!connection.IsConnected) - { - Console.WriteLine("Did not connect to Redis."); - } - - return connection; - }; - }); -``` - -:::moniker-end - -:::moniker range="> aspnetcore-2.1" - -```csharp -services.AddSignalR() - .AddMessagePackProtocol() - .AddStackExchangeRedis(o => - { - o.ConnectionFactory = async writer => - { - var config = new ConfigurationOptions - { - AbortOnConnectFail = false - }; - config.EndPoints.Add(IPAddress.Loopback, 0); - config.SetDefaultPorts(); - var connection = await ConnectionMultiplexer.ConnectAsync(config, writer); - connection.ConnectionFailed += (_, e) => - { - Console.WriteLine("Connection to Redis failed."); - }; - - if (!connection.IsConnected) - { - Console.WriteLine("Did not connect to Redis."); - } - - return connection; - }; - }); -``` - -:::moniker-end - -## Redis Cluster - -[Redis Cluster](https://redis.io/topics/cluster-spec) utilizes multiple simultaneously active Redis servers to achieve high availability. When Redis Cluster is used as the backplane for SignalR, messages are delivered to all of the nodes of the cluster without code modifications to the app. - -There's a tradeoff between the number of nodes in the cluster and the throughput of the backplane. Increasing the number of nodes increases the availability of the cluster but decreases the throughput because messages must be transmitted to all of the nodes in the cluster. - -In the SignalR app, include all of the possible Redis nodes using either of the following approaches: - -* List the nodes in the connection string delimited with commas. -* If using custom behavior for connection failures, add the nodes to [`ConfigurationOptions.Endpoints`](https://stackexchange.github.io/StackExchange.Redis/Configuration#configuration-options). - -## Next steps - -For more information, see the following resources: - -* -* [Redis documentation](https://redis.io/documentation) -* [StackExchange Redis documentation](https://stackexchange.github.io/StackExchange.Redis/) -* [Azure Redis Cache documentation](/azure/azure-cache-for-redis/) - -:::moniker-end diff --git a/aspnetcore/tutorials/first-mvc-app/details/includes/details9.md b/aspnetcore/tutorials/first-mvc-app/details/includes/details9.md deleted file mode 100644 index 508dbd874bec..000000000000 --- a/aspnetcore/tutorials/first-mvc-app/details/includes/details9.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -ai-usage: ai-assisted -ms.date: 10/15/2026 ---- - -:::moniker range="= aspnetcore-9.0" - -Open the Movie controller and examine the `Details` method: - -[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie90/Controllers/MoviesController.cs?name=snippet_Details)] - -The MVC scaffolding engine that created this action method adds a comment showing an HTTP request that invokes the method. In this case it's a GET request with three URL segments, the `Movies` controller, the `Details` method, and an `id` value. Recall these segments are defined in `Program.cs`. - -[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie90/Program.cs?highlight=3&name=snippet_MapControllerRoute)] - -EF makes it easy to search for data using the `FirstOrDefaultAsync` method. An important security feature built into the method is that the code verifies that the search method has found a movie before it tries to do anything with it. For example, a hacker could introduce errors into the site by changing the URL created by the links from `http://localhost:{PORT}/Movies/Details/1` to something like `http://localhost:{PORT}/Movies/Details/12345` (or some other value that doesn't represent an actual movie). If you didn't check for a null movie, the app would throw an exception. - -Examine the `Delete` and `DeleteConfirmed` methods. - -[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie90/Controllers/MoviesController.cs?name=snippet_Delete)] - -Note that the `HTTP GET Delete` method doesn't delete the specified movie, it returns a view of the movie where you can submit (HttpPost) the deletion. Performing a delete operation in response to a GET request (or for that matter, performing an edit operation, create operation, or any other operation that changes data) opens up a security hole. - -The `[HttpPost]` method that deletes the data is named `DeleteConfirmed` to give the HTTP POST method a unique signature or name. The two method signatures are shown below: - -[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie90/Controllers/MoviesController.cs?name=snippet_DeleteSignature)] - -[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie90/Controllers/MoviesController.cs?name=snippet_DeleteConfirmedSignature)] - -The common language runtime (CLR) requires overloaded methods to have a unique parameter signature (same method name but different list of parameters). However, here you need two `Delete` methods -- one for GET and one for POST -- that both have the same parameter signature. (They both need to accept a single integer as a parameter.) - -There are two approaches to this problem, one is to give the methods different names. That's what the scaffolding mechanism did in the preceding example. However, this introduces a small problem: ASP.NET maps segments of a URL to action methods by name, and if you rename a method, routing normally wouldn't be able to find that method. The solution is what you see in the example, which is to add the `ActionName("Delete")` attribute to the `DeleteConfirmed` method. That attribute performs mapping for the routing system so that a URL that includes /Delete/ for a POST request will find the `DeleteConfirmed` method. - -Another common work around for methods that have identical names and signatures is to artificially change the signature of the POST method to include an extra (unused) parameter. That's what we did in a previous post when we added the `notUsed` parameter. You could do the same thing here for the `[HttpPost] Delete` method: - -```csharp -// POST: Movies/Delete/6 -[HttpPost] -[ValidateAntiForgeryToken] -public async Task Delete(int id, bool notUsed) -``` - -### Publish to Azure - -For information on deploying to Azure, see [Tutorial: Build an ASP.NET Core and SQL Database app in Azure App Service](/azure/app-service/tutorial-dotnetcore-sqldb-app). - -[!INCLUDE[](~/includes/reliableWAP_H2.md)] - -> [!div class="step-by-step"] -> [Previous](~/tutorials/first-mvc-app/validation.md) - -:::moniker-end