From 29372addc94f49f92cf8b5743a13c09de75609d2 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Tue, 29 Apr 2025 11:06:36 -0600 Subject: [PATCH 01/15] SFI docker-compose-https.md (#35308) --- aspnetcore/security/docker-compose-https.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aspnetcore/security/docker-compose-https.md b/aspnetcore/security/docker-compose-https.md index c2c764bcec4d..6d2415c28b79 100644 --- a/aspnetcore/security/docker-compose-https.md +++ b/aspnetcore/security/docker-compose-https.md @@ -76,7 +76,7 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Password=-\0pw- - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx volumes: - ~/.aspnet/https:/https:ro @@ -116,7 +116,7 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Password=-\0pw- - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx volumes: - ~/.aspnet/https:/https:ro @@ -154,7 +154,7 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Password=-\0pw- - ASPNETCORE_Kestrel__Certificates__Default__Path=C:\https\aspnetapp.pfx volumes: - ${USERPROFILE}\.aspnet\https:C:\https:ro From 95ecc7a6105d307f85523e1e993d727f682d0216 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Tue, 29 Apr 2025 20:03:56 +0200 Subject: [PATCH 02/15] make snippet tablet-friendly --- .../fundamentals/openapi/include-metadata.md | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/aspnetcore/fundamentals/openapi/include-metadata.md b/aspnetcore/fundamentals/openapi/include-metadata.md index 81928c621e7e..87a3781427da 100644 --- a/aspnetcore/fundamentals/openapi/include-metadata.md +++ b/aspnetcore/fundamentals/openapi/include-metadata.md @@ -176,7 +176,8 @@ The following sample demonstrates how to set a description for a parameter. ```csharp [HttpGet("attributes")] -public IResult Attributes([Description("This is a description.")] string name) +public IResult Attributes( + [Description("This is a description.")] string name) { return Results.Ok("Hello world!"); } @@ -218,9 +219,16 @@ The framework uses the { - public static async ValueTask BindAsync(HttpContext context, ParameterInfo parameter) + 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)); @@ -400,9 +410,9 @@ All of the above attributes can be applied to individual action methods or to th ```csharp [HttpGet("/todos/{id}")] -[ProducesResponseType(StatusCodes.Status200OK, +[ProducesResponseType(StatusCodes.Status200OK, "application/json", Description = "Returns the requested Todo item.")] -[ProducesResponseType(StatusCodes.Status404NotFound, +[ProducesResponseType(StatusCodes.Status404NotFound, Description = "Requested Todo item not found.")] [ProducesDefault(Description = "Undocumented status code.")] public async Task> GetTodoItem(string id, Todo todo) @@ -422,9 +432,12 @@ In controller-based apps, ASP.NET responds with a ProblemDetails response type w ```csharp [HttpPut("/todos/{id}")] -[ProducesResponseType(StatusCodes.Status200OK, "application/json")] -[ProducesResponseType(StatusCodes.Status201Created, "application/json")] -[ProducesResponseType(StatusCodes.Status400BadRequest, "application/problem+json")] +[ProducesResponseType(StatusCodes.Status200OK, + "application/json")] +[ProducesResponseType(StatusCodes.Status201Created, + "application/json")] +[ProducesResponseType(StatusCodes.Status400BadRequest, + "application/problem+json")] public async Task> CreateOrReplaceTodo(string id, Todo todo) ``` @@ -623,7 +636,12 @@ A special case is when an enum type has the `[Flags]` attribute, which indicates ```csharp [Flags, JsonConverter(typeof(JsonStringEnumConverter))] -public enum PizzaToppings { Pepperoni = 1, Sausage = 2, Mushrooms = 4, Anchovies = 8 } +public enum PizzaToppings { + Pepperoni = 1, + Sausage = 2, + Mushrooms = 4, + Anchovies = 8 +} ``` An enum type without a [`[JsonConverter]`](xref:System.Text.Json.Serialization.JsonConverterAttribute) will be defined as `type: integer` in the generated schema. @@ -670,19 +688,19 @@ A schema transformer can be used to override any default metadata or add additio ## Set JSON serialization options globally -The following code configures some JSON options globally, for Minimal APIs and Controler based APIs: +The following code configures some JSON options globally, for Minimal APIs and Controller based APIs: - [!code-csharp[](~/fundamentals/openapi/samples/10.x/WebJson/Program.cs?highlight=8-29)] + [!code-csharp[](~/fundamentals/openapi/samples/10.x/WebJson/Program.cs?highlight=9-29)] ## MVC JSON options and global JSON options -The following table shows the key Differences beween the MVC JSON options and global Minimal API JSON options: +The following table shows the key differences beween the MVC JSON options and global Minimal API JSON options: | **Aspect** | **MVC JSON Options** | **Global JSON Options** | |-----------------------|--------------------------------------------|-----------------------------------------------| -| **Scope** | Limited to MVC controllers and endpoints. | Minimal Api's and OpenAPI docs. | +| **Scope** | Limited to MVC controllers and endpoints. | Minimal APIs and OpenAPI docs. | | **Configuration** | `AddControllers().AddJsonOptions()` | `Configure()` | -| **Purpose** | Handles serialization and deserializtion of JSON requests and responses in APIs. | Defines global JSON handling for Minimal APIs and OpenAPI schemas. | +| **Purpose** | Handles serialization and deserialization of JSON requests and responses in APIs. | Defines global JSON handling for Minimal APIs and OpenAPI schemas. | | **Influence on OpenAPI** | None | Directly influences OpenAPI schema generation.| --- From 1e3dc2f028ed5a9203c41fd94e1cb3729405b532 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Tue, 29 Apr 2025 20:17:23 +0200 Subject: [PATCH 03/15] fix typo --- aspnetcore/fundamentals/openapi/include-metadata.md | 2 +- aspnetcore/release-notes/aspnetcore-10/includes/openApi.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aspnetcore/fundamentals/openapi/include-metadata.md b/aspnetcore/fundamentals/openapi/include-metadata.md index 87a3781427da..c06b4cdd4d81 100644 --- a/aspnetcore/fundamentals/openapi/include-metadata.md +++ b/aspnetcore/fundamentals/openapi/include-metadata.md @@ -648,7 +648,7 @@ An enum type without a [`[JsonConverter]`](xref:System.Text.Json.Serialization. **Note:** The [`[AllowedValues]`](xref:System.ComponentModel.DataAnnotations.AllowedValuesAttribute) attribute does not set the `enum` values of a property. -[Set JSON options globally](#set-json-serialization-options-globally) shows how to set the the `JsonStringEnumConverter` globally. +[Set JSON options globally](#set-json-serialization-options-globally) shows how to set the `JsonStringEnumConverter` globally. #### nullable diff --git a/aspnetcore/release-notes/aspnetcore-10/includes/openApi.md b/aspnetcore/release-notes/aspnetcore-10/includes/openApi.md index 867c0e026738..e0ee5beadd3d 100644 --- a/aspnetcore/release-notes/aspnetcore-10/includes/openApi.md +++ b/aspnetcore/release-notes/aspnetcore-10/includes/openApi.md @@ -80,7 +80,7 @@ app.MapOpenApi("/openapi/{documentName}.yaml"); Support for: -* YAML is currently only available for the the OpenAPI served from the OpenAPI endpoint. +* YAML is currently only available for the OpenAPI served from the OpenAPI endpoint. * Generating OpenAPI documents in YAML format at build time is added in a future preview. See [this PR](https://github.com/dotnet/aspnetcore/pull/58616) which added support for serving the generated OpenAPI document in YAML format. From 118d7cc262534809140d3049126f49e5120d3f88 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Tue, 29 Apr 2025 15:24:02 -0400 Subject: [PATCH 04/15] Fix typo (#35324) --- aspnetcore/blazor/tutorials/movie-database-app/part-3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-3.md b/aspnetcore/blazor/tutorials/movie-database-app/part-3.md index 8c49446da3c6..f30e086eb487 100644 --- a/aspnetcore/blazor/tutorials/movie-database-app/part-3.md +++ b/aspnetcore/blazor/tutorials/movie-database-app/part-3.md @@ -68,7 +68,7 @@ The `NavMenu` component (`Components/Layout/NavMenu.razor`) implements sidebar n A component behaves like an `` element, except it toggles an `active` CSS class based on whether its `href` matches the current URL. The `active` class helps a user understand which page is the active page among the navigation links displayed. assigned to the parameter configures the component to display an active CSS class when it matches the entire current URL. -The component built into the Blazor framework for any Blazor app to use, while the `NavMenu` component is only part of Blazor project templates. +The component is built into the Blazor framework for any Blazor app to use, while the `NavMenu` component is only part of Blazor project templates. `Components/Layout/NavMenu.razor`: From 873b002329a1310e79c5a3607214a0396d41d1d7 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Tue, 29 Apr 2025 18:40:10 -0400 Subject: [PATCH 05/15] Patch code example (#35326) --- aspnetcore/diagnostics/asp0025.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/diagnostics/asp0025.md b/aspnetcore/diagnostics/asp0025.md index d3154df3b1a2..97dd7138743c 100644 --- a/aspnetcore/diagnostics/asp0025.md +++ b/aspnetcore/diagnostics/asp0025.md @@ -76,7 +76,7 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddAuthorizationBuilder() .AddPolicy("AtLeast21", policy => { - policy.Requirements.Add(new MinimumAgeRequirement(21))); + policy.Requirements.Add(new MinimumAgeRequirement(21)); }); var app = builder.Build(); From 4773d8a35a7ff75b916a6160ae2dd4ffa471e54b Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Wed, 30 Apr 2025 07:31:57 +0800 Subject: [PATCH 06/15] Update grpcweb.md to remove obsolete configuration (#35327) Co-authored-by: Wade Pickett --- aspnetcore/grpc/grpcweb.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aspnetcore/grpc/grpcweb.md b/aspnetcore/grpc/grpcweb.md index 5f6b39261e93..52da4c0e3a17 100644 --- a/aspnetcore/grpc/grpcweb.md +++ b/aspnetcore/grpc/grpcweb.md @@ -4,7 +4,7 @@ author: jamesnk description: Learn how to configure gRPC services on ASP.NET Core to be callable from browser apps using gRPC-Web. monikerRange: '>= aspnetcore-3.0' ms.author: wpickett -ms.date: 06/30/2020 +ms.date: 04/29/2025 uid: grpc/grpcweb --- # gRPC-Web in ASP.NET Core gRPC apps @@ -134,7 +134,8 @@ The preceding code: * `GrpcWebMode`: An enumeration type that specifies whether the gRPC HTTP request `Content-Type` is `application/grpc-web` or `application/grpc-web-text`. * `GrpcWebMode.GrpcWeb` configures sending content without encoding. Default value. * `GrpcWebMode.GrpcWebText` configures base64-encoded content. Required for server streaming calls in browsers. -* `HttpVersion`: HTTP protocol `Version` used to set on the underlying gRPC HTTP request. gRPC-Web doesn't require a specific version and doesn't override the default unless specified. + +`GrpcChannelOptions.HttpVersion` and `GrpcChannelOptions.HttpVersionPolicy` can be used to configure the HTTP protocol version. > [!IMPORTANT] > Generated gRPC clients have synchronous and asynchronous methods for calling unary methods. For example, `SayHello` is synchronous, and `SayHelloAsync` is asynchronous. Asynchronous methods are always required in Blazor WebAssembly. Calling a synchronous method in a Blazor WebAssembly app causes the app to become unresponsive. From 25b78de4f41f63924fdb4e633d8b8e88140fef8d Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Thu, 1 May 2025 16:59:37 -0400 Subject: [PATCH 07/15] Fix typo (#35335) --- aspnetcore/blazor/security/additional-scenarios.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/blazor/security/additional-scenarios.md b/aspnetcore/blazor/security/additional-scenarios.md index 852f10abd544..7eaf07799273 100644 --- a/aspnetcore/blazor/security/additional-scenarios.md +++ b/aspnetcore/blazor/security/additional-scenarios.md @@ -32,7 +32,7 @@ For Blazor Server, view the [7.0 version of this article section](xref:blazor/se ## Reading tokens from `HttpContext` -Reading tokens from , including as a as a [cascading parameter](xref:Microsoft.AspNetCore.Components.CascadingParameterAttribute), using is supported for obtaining tokens for use during interactive server rendering if the tokens are obtained during static server-side rendering (static SSR) or prerendering. However, tokens aren't updated if the user authenticates after the circuit is established, since the is captured at the start of the SignalR connection. Also, the use of by means that you must be careful not to lose the execution context before reading the . +Reading tokens from , including as a [cascading parameter](xref:Microsoft.AspNetCore.Components.CascadingParameterAttribute), using is supported for obtaining tokens for use during interactive server rendering if the tokens are obtained during static server-side rendering (static SSR) or prerendering. However, tokens aren't updated if the user authenticates after the circuit is established, since the is captured at the start of the SignalR connection. Also, the use of by means that you must be careful not to lose the execution context before reading the . For more information, see . From 9f96d1f65555708b613f1966d003070ae32b0519 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Fri, 2 May 2025 10:44:22 -0600 Subject: [PATCH 08/15] SFI docker-compose-https7.md (#35331) * SFI docker-compose-https7.md * Apply suggestions from code review --- aspnetcore/security/includes/docker-compose-https7.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/aspnetcore/security/includes/docker-compose-https7.md b/aspnetcore/security/includes/docker-compose-https7.md index 7733a35e90ff..3d1419f6dfc6 100644 --- a/aspnetcore/security/includes/docker-compose-https7.md +++ b/aspnetcore/security/includes/docker-compose-https7.md @@ -65,12 +65,13 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Password=-\0pw- - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx volumes: - ~/.aspnet/https:/https:ro ``` -The password specified in the docker compose file must match the password used for the certificate. +The password specified in the docker compose file must match the password used for the certificate. In the preceding commands, replace `-\0pw-` with a password. + Start the container with ASP.NET Core configured for HTTPS: @@ -143,12 +144,14 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=https://+:443;http://+:80 - - ASPNETCORE_Kestrel__Certificates__Default__Password=password + - ASPNETCORE_Kestrel__Certificates__Default__Password=-\0pw- - ASPNETCORE_Kestrel__Certificates__Default__Path=C:\https\aspnetapp.pfx volumes: - ${USERPROFILE}\.aspnet\https:C:\https:ro ``` -The password specified in the docker compose file must match the password used for the certificate. +```suggestion +The password specified in the docker compose file must match the password used for the certificate. In the preceding commands, replace `-\0pw-` with a password. + Start the container with ASP.NET Core configured for HTTPS: From 550ffacb53a48adbd3edc48877f8268fa3111537 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Fri, 2 May 2025 12:44:44 -0600 Subject: [PATCH 09/15] mon prep debug remove startup /2 (#35337) * Update debug remove startup /2 * Update debug remove startup /2 * Update debug remove startup /2 --- aspnetcore/test/troubleshoot.md | 6 + .../test/troubleshoot/code/5.x/Program.cs | 75 ++++++++ .../troubleshoot/includes/troubleshoot5.md | 160 ++++++++++++++++++ 3 files changed, 241 insertions(+) create mode 100644 aspnetcore/test/troubleshoot/code/5.x/Program.cs create mode 100644 aspnetcore/test/troubleshoot/includes/troubleshoot5.md diff --git a/aspnetcore/test/troubleshoot.md b/aspnetcore/test/troubleshoot.md index 8a1d324c83e9..bb1320050e67 100644 --- a/aspnetcore/test/troubleshoot.md +++ b/aspnetcore/test/troubleshoot.md @@ -9,6 +9,8 @@ uid: test/troubleshoot --- # Troubleshoot and debug ASP.NET Core projects +:::moniker range=">= aspnetcore-6.0" + By [Rick Anderson](https://twitter.com/RickAndMSFT) The following links provide troubleshooting guidance: @@ -165,3 +167,7 @@ The following links provide information on debugging ASP.NET Core apps. * [Debugging .NET Core on Unix over SSH](https://devblogs.microsoft.com/devops/debugging-net-core-on-unix-over-ssh/) * [Quickstart: Debug ASP.NET with the Visual Studio debugger](/visualstudio/debugger/quickstart-debug-aspnet) * See [this GitHub issue](https://github.com/dotnet/AspNetCore.Docs/issues/2960) for more debugging information. + +:::moniker-end + +[!INCLUDE[](~/test/troubleshoot/includes/troubleshoot5.md)] diff --git a/aspnetcore/test/troubleshoot/code/5.x/Program.cs b/aspnetcore/test/troubleshoot/code/5.x/Program.cs new file mode 100644 index 000000000000..9e11088e14b2 --- /dev/null +++ b/aspnetcore/test/troubleshoot/code/5.x/Program.cs @@ -0,0 +1,75 @@ +// This is a copy/paste from the previous version embedded in the MD file, used only for productive +// GitHub diff +public void Configure(IApplicationBuilder app, IHostingEnvironment env, + IConfiguration config) +{ + if (env.IsDevelopment()) + { + app.Run(async (context) => + { + var sb = new StringBuilder(); + var nl = System.Environment.NewLine; + var rule = string.Concat(nl, new string('-', 40), nl); + var authSchemeProvider = app.ApplicationServices + .GetRequiredService(); + + sb.Append($"Request{rule}"); + sb.Append($"{DateTimeOffset.Now}{nl}"); + sb.Append($"{context.Request.Method} {context.Request.Path}{nl}"); + sb.Append($"Scheme: {context.Request.Scheme}{nl}"); + sb.Append($"Host: {context.Request.Headers["Host"]}{nl}"); + sb.Append($"PathBase: {context.Request.PathBase.Value}{nl}"); + sb.Append($"Path: {context.Request.Path.Value}{nl}"); + sb.Append($"Query: {context.Request.QueryString.Value}{nl}{nl}"); + + sb.Append($"Connection{rule}"); + sb.Append($"RemoteIp: {context.Connection.RemoteIpAddress}{nl}"); + sb.Append($"RemotePort: {context.Connection.RemotePort}{nl}"); + sb.Append($"LocalIp: {context.Connection.LocalIpAddress}{nl}"); + sb.Append($"LocalPort: {context.Connection.LocalPort}{nl}"); + sb.Append($"ClientCert: {context.Connection.ClientCertificate}{nl}{nl}"); + + sb.Append($"Identity{rule}"); + sb.Append($"User: {context.User.Identity.Name}{nl}"); + var scheme = await authSchemeProvider + .GetSchemeAsync(IISDefaults.AuthenticationScheme); + sb.Append($"DisplayName: {scheme?.DisplayName}{nl}{nl}"); + + sb.Append($"Headers{rule}"); + foreach (var header in context.Request.Headers) + { + sb.Append($"{header.Key}: {header.Value}{nl}"); + } + sb.Append(nl); + + sb.Append($"WebSockets{rule}"); + if (context.Features.Get() != null) + { + sb.Append($"Status: Enabled{nl}{nl}"); + } + else + { + sb.Append($"Status: Disabled{nl}{nl}"); + } + + sb.Append($"Configuration{rule}"); + foreach (var pair in config.AsEnumerable()) + { + sb.Append($"{pair.Path}: {pair.Value}{nl}"); + } + sb.Append(nl); + + sb.Append($"Environment Variables{rule}"); + var vars = System.Environment.GetEnvironmentVariables(); + foreach (var key in vars.Keys.Cast().OrderBy(key => key, + StringComparer.OrdinalIgnoreCase)) + { + var value = vars[key]; + sb.Append($"{key}: {value}{nl}"); + } + + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync(sb.ToString()); + }); + } +} diff --git a/aspnetcore/test/troubleshoot/includes/troubleshoot5.md b/aspnetcore/test/troubleshoot/includes/troubleshoot5.md new file mode 100644 index 000000000000..624a34e3b1db --- /dev/null +++ b/aspnetcore/test/troubleshoot/includes/troubleshoot5.md @@ -0,0 +1,160 @@ +:::moniker range="< aspnetcore-6.0" + +By [Rick Anderson](https://twitter.com/RickAndMSFT) + +The following links provide troubleshooting guidance: + +* +* +* [NDC Conference (London, 2018): Diagnosing issues in ASP.NET Core Applications](https://www.youtube.com/watch?v=RYI0DHoIVaA) +* [ASP.NET Blog: Troubleshooting ASP.NET Core Performance Problems](https://blogs.msdn.microsoft.com/webdev/2018/05/23/asp-net-core-performance-improvements/) + +## .NET Core SDK warnings + +### Both the 32-bit and 64-bit versions of the .NET Core SDK are installed + +In the **New Project** dialog for ASP.NET Core, you may see the following warning: + +> Both 32-bit and 64-bit versions of the .NET Core SDK are installed. Only templates from the 64-bit versions installed at 'C:\\Program Files\\dotnet\\sdk\\' are displayed. + +This warning appears when both 32-bit (x86) and 64-bit (x64) versions of the [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet-core) are installed. Common reasons both versions may be installed include: + +* You originally downloaded the .NET Core SDK installer using a 32-bit machine but then copied it across and installed it on a 64-bit machine. +* The 32-bit .NET Core SDK was installed by another application. +* The wrong version was downloaded and installed. + +Uninstall the 32-bit .NET Core SDK to prevent this warning. Uninstall from **Control Panel** > **Programs and Features** > **Uninstall or change a program**. If you understand why the warning occurs and its implications, you can ignore the warning. + +### The .NET Core SDK is installed in multiple locations + +In the **New Project** dialog for ASP.NET Core, you may see the following warning: + +> The .NET Core SDK is installed in multiple locations. Only templates from the SDKs installed at 'C:\\Program Files\\dotnet\\sdk\\' are displayed. + +You see this message when you have at least one installation of the .NET Core SDK in a directory outside of *C:\\Program Files\\dotnet\\sdk\\*. Usually this happens when the .NET Core SDK has been deployed on a machine using copy/paste instead of the MSI installer. + +Uninstall all 32-bit .NET Core SDKs and runtimes to prevent this warning. Uninstall from **Control Panel** > **Programs and Features** > **Uninstall or change a program**. If you understand why the warning occurs and its implications, you can ignore the warning. + +### No .NET Core SDKs were detected + +* In the Visual Studio **New Project** dialog for ASP.NET Core, you may see the following warning: + + > No .NET Core SDKs were detected, ensure they are included in the environment variable `PATH`. + +* When executing a `dotnet` command, the warning appears as: + + > It was not possible to find any installed dotnet SDKs. + +These warnings appear when the environment variable `PATH` doesn't point to any .NET Core SDKs on the machine. To resolve this problem: + +* Install the .NET Core SDK. Obtain the latest installer from [.NET Downloads](https://dotnet.microsoft.com/download). +* Verify that the `PATH` environment variable points to the location where the SDK is installed (`C:\Program Files\dotnet\` for 64-bit/x64 or `C:\Program Files (x86)\dotnet\` for 32-bit/x86). The SDK installer normally sets the `PATH`. Always install the same bitness SDKs and runtimes on the same machine. + +### Missing SDK after installing the .NET Core Hosting Bundle + +Installing the [.NET Core Hosting Bundle](xref:host-and-deploy/iis/index#install-the-net-core-hosting-bundle) modifies the `PATH` when it installs the .NET Core runtime to point to the 32-bit (x86) version of .NET Core (`C:\Program Files (x86)\dotnet\`). This can result in missing SDKs when the 32-bit (x86) .NET Core `dotnet` command is used ([No .NET Core SDKs were detected](#no-net-core-sdks-were-detected)). To resolve this problem, move `C:\Program Files\dotnet\` to a position before `C:\Program Files (x86)\dotnet\` on the `PATH`. + +## Obtain data from an app + +If an app is capable of responding to requests, you can obtain the following data from the app using middleware: + +* Request: Method, scheme, host, pathbase, path, query string, headers +* Connection: Remote IP address, remote port, local IP address, local port, client certificate +* Identity: Name, display name +* Configuration settings +* Environment variables + +Place the following [middleware](xref:fundamentals/middleware/index#create-a-middleware-pipeline-with-iapplicationbuilder) code at the beginning of the `Startup.Configure` method's request processing pipeline. The environment is checked before the middleware is run to ensure that the code is only executed in the Development environment. + +To obtain the environment, use either of the following approaches: + +* Inject the `IHostingEnvironment` into the `Startup.Configure` method and check the environment with the local variable. The following sample code demonstrates this approach. + +* Assign the environment to a property in the `Startup` class. Check the environment using the property (for example, `if (Environment.IsDevelopment())`). + +```csharp +public void Configure(IApplicationBuilder app, IHostingEnvironment env, + IConfiguration config) +{ + if (env.IsDevelopment()) + { + app.Run(async (context) => + { + var sb = new StringBuilder(); + var nl = System.Environment.NewLine; + var rule = string.Concat(nl, new string('-', 40), nl); + var authSchemeProvider = app.ApplicationServices + .GetRequiredService(); + + sb.Append($"Request{rule}"); + sb.Append($"{DateTimeOffset.Now}{nl}"); + sb.Append($"{context.Request.Method} {context.Request.Path}{nl}"); + sb.Append($"Scheme: {context.Request.Scheme}{nl}"); + sb.Append($"Host: {context.Request.Headers["Host"]}{nl}"); + sb.Append($"PathBase: {context.Request.PathBase.Value}{nl}"); + sb.Append($"Path: {context.Request.Path.Value}{nl}"); + sb.Append($"Query: {context.Request.QueryString.Value}{nl}{nl}"); + + sb.Append($"Connection{rule}"); + sb.Append($"RemoteIp: {context.Connection.RemoteIpAddress}{nl}"); + sb.Append($"RemotePort: {context.Connection.RemotePort}{nl}"); + sb.Append($"LocalIp: {context.Connection.LocalIpAddress}{nl}"); + sb.Append($"LocalPort: {context.Connection.LocalPort}{nl}"); + sb.Append($"ClientCert: {context.Connection.ClientCertificate}{nl}{nl}"); + + sb.Append($"Identity{rule}"); + sb.Append($"User: {context.User.Identity.Name}{nl}"); + var scheme = await authSchemeProvider + .GetSchemeAsync(IISDefaults.AuthenticationScheme); + sb.Append($"DisplayName: {scheme?.DisplayName}{nl}{nl}"); + + sb.Append($"Headers{rule}"); + foreach (var header in context.Request.Headers) + { + sb.Append($"{header.Key}: {header.Value}{nl}"); + } + sb.Append(nl); + + sb.Append($"WebSockets{rule}"); + if (context.Features.Get() != null) + { + sb.Append($"Status: Enabled{nl}{nl}"); + } + else + { + sb.Append($"Status: Disabled{nl}{nl}"); + } + + sb.Append($"Configuration{rule}"); + foreach (var pair in config.AsEnumerable()) + { + sb.Append($"{pair.Path}: {pair.Value}{nl}"); + } + sb.Append(nl); + + sb.Append($"Environment Variables{rule}"); + var vars = System.Environment.GetEnvironmentVariables(); + foreach (var key in vars.Keys.Cast().OrderBy(key => key, + StringComparer.OrdinalIgnoreCase)) + { + var value = vars[key]; + sb.Append($"{key}: {value}{nl}"); + } + + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync(sb.ToString()); + }); + } +} +``` + +## Debug ASP.NET Core apps + +The following links provide information on debugging ASP.NET Core apps. + +* [Debugging ASP Core on Linux](https://devblogs.microsoft.com/premier-developer/debugging-asp-core-on-linux-with-visual-studio-2017/) +* [Debugging .NET Core on Unix over SSH](https://devblogs.microsoft.com/devops/debugging-net-core-on-unix-over-ssh/) +* [Quickstart: Debug ASP.NET with the Visual Studio debugger](/visualstudio/debugger/quickstart-debug-aspnet) +* See [this GitHub issue](https://github.com/dotnet/AspNetCore.Docs/issues/2960) for more debugging information. + +:::moniker-end From a29ecfeea1168a65f441730bc10df903c1731f04 Mon Sep 17 00:00:00 2001 From: Wade Pickett Date: Fri, 2 May 2025 20:37:42 -0700 Subject: [PATCH 10/15] Meta author clean up (#35340) Updated meta author to match ms.author for a collection of articles per management request. --- aspnetcore/client-side/bundling-and-minification.md | 2 +- aspnetcore/client-side/libman/index.md | 2 +- aspnetcore/client-side/libman/libman-cli.md | 2 +- aspnetcore/client-side/libman/libman-vs.md | 2 +- aspnetcore/client-side/spa-services.md | 2 +- aspnetcore/client-side/spa/intro.md | 2 +- aspnetcore/fundamentals/metapackage-app.md | 2 +- aspnetcore/fundamentals/minimal-apis.md | 2 +- aspnetcore/fundamentals/minimal-apis/min-api-filters.md | 2 +- aspnetcore/fundamentals/minimal-apis/parameter-binding.md | 2 +- aspnetcore/fundamentals/minimal-apis/route-handlers.md | 2 +- aspnetcore/fundamentals/minimal-apis/test-min-api.md | 2 +- aspnetcore/fundamentals/minimal-apis/webapplication.md | 2 +- aspnetcore/fundamentals/openapi/overview.md | 2 +- aspnetcore/fundamentals/startup.md | 2 +- aspnetcore/fundamentals/target-aspnetcore.md | 2 +- aspnetcore/host-and-deploy/azure-apps/index.md | 2 +- aspnetcore/host-and-deploy/docker/building-net-docker-images.md | 2 +- aspnetcore/host-and-deploy/docker/index.md | 2 +- aspnetcore/index.yml | 2 +- aspnetcore/migration/1x-to-2x/identity-2x.md | 2 +- aspnetcore/migration/1x-to-2x/index.md | 2 +- aspnetcore/migration/21-to-22.md | 2 +- aspnetcore/migration/30-to-31.md | 2 +- aspnetcore/migration/31-to-50.md | 2 +- aspnetcore/mvc/views/tag-helpers/built-in/partial-tag-helper.md | 2 +- aspnetcore/mvc/views/tag-helpers/th-components.md | 2 +- aspnetcore/security/authorization/resourcebased.md | 2 +- aspnetcore/security/docker-https.md | 2 +- aspnetcore/signalr/api-design.md | 2 +- aspnetcore/signalr/authn-and-authz.md | 2 +- aspnetcore/signalr/background-services.md | 2 +- aspnetcore/signalr/client-features.md | 2 +- aspnetcore/signalr/configuration.md | 2 +- aspnetcore/signalr/diagnostics.md | 2 +- aspnetcore/signalr/dotnet-client.md | 2 +- aspnetcore/signalr/groups.md | 2 +- aspnetcore/signalr/hubcontext.md | 2 +- aspnetcore/signalr/hubs.md | 2 +- aspnetcore/signalr/introduction.md | 2 +- aspnetcore/signalr/javascript-client.md | 2 +- aspnetcore/signalr/messagepackhubprotocol.md | 2 +- aspnetcore/signalr/publish-to-azure-web-app.md | 2 +- aspnetcore/signalr/redis-backplane.md | 2 +- aspnetcore/signalr/scale.md | 2 +- aspnetcore/signalr/security.md | 2 +- aspnetcore/signalr/streaming.md | 2 +- aspnetcore/signalr/supported-platforms.md | 2 +- aspnetcore/signalr/troubleshoot.md | 2 +- aspnetcore/signalr/version-differences.md | 2 +- aspnetcore/test/debug-aspnetcore-source.md | 2 +- aspnetcore/tutorials/signalr.md | 2 +- 52 files changed, 52 insertions(+), 52 deletions(-) diff --git a/aspnetcore/client-side/bundling-and-minification.md b/aspnetcore/client-side/bundling-and-minification.md index 0b9efd992cb3..0fc74ab6983a 100644 --- a/aspnetcore/client-side/bundling-and-minification.md +++ b/aspnetcore/client-side/bundling-and-minification.md @@ -1,6 +1,6 @@ --- title: Bundle and minify static assets in ASP.NET Core -author: rick-anderson +author: wadepickett description: Learn how to optimize static resources in an ASP.NET Core web application by applying bundling and minification techniques. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/client-side/libman/index.md b/aspnetcore/client-side/libman/index.md index 122c55a66ef7..a4617cfbe8f2 100644 --- a/aspnetcore/client-side/libman/index.md +++ b/aspnetcore/client-side/libman/index.md @@ -1,6 +1,6 @@ --- title: Client-side library acquisition in ASP.NET Core with LibMan -author: rick-anderson +author: wadepickett description: Learn how to install client-side library assets in an ASP.NET Core project using Library Manager (LibMan). ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/client-side/libman/libman-cli.md b/aspnetcore/client-side/libman/libman-cli.md index b3987607ec51..d9c0f50096f2 100644 --- a/aspnetcore/client-side/libman/libman-cli.md +++ b/aspnetcore/client-side/libman/libman-cli.md @@ -1,6 +1,6 @@ --- title: Use the LibMan CLI with ASP.NET Core -author: rick-anderson +author: wadepickett description: Learn how to use the LibMan CLI in an ASP.NET Core project. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/client-side/libman/libman-vs.md b/aspnetcore/client-side/libman/libman-vs.md index 38788605c7d8..5adcfe1c82b9 100644 --- a/aspnetcore/client-side/libman/libman-vs.md +++ b/aspnetcore/client-side/libman/libman-vs.md @@ -1,6 +1,6 @@ --- title: Use LibMan with ASP.NET Core in Visual Studio -author: rick-anderson +author: wadepickett description: Learn how to use LibMan in an ASP.NET Core project with Visual Studio. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/client-side/spa-services.md b/aspnetcore/client-side/spa-services.md index b9cf19abf468..16cbfc4a2f20 100644 --- a/aspnetcore/client-side/spa-services.md +++ b/aspnetcore/client-side/spa-services.md @@ -1,6 +1,6 @@ --- title: The features described in this article are obsolete as of ASP.NET Core 3.0 -author: rick-anderson +author: wadepickett description: The features described in this article are obsolete as of ASP.NET Core 3.0 monikerRange: '>= aspnetcore-2.1 <= aspnetcore-3.0' ms.author: wpickett diff --git a/aspnetcore/client-side/spa/intro.md b/aspnetcore/client-side/spa/intro.md index 276ad5ee1ad8..c672548fdd99 100644 --- a/aspnetcore/client-side/spa/intro.md +++ b/aspnetcore/client-side/spa/intro.md @@ -1,6 +1,6 @@ --- title: Overview of Single Page Apps (SPAs) in ASP.NET Core -author: rick-anderson +author: wadepickett ms.author: wpickett monikerRange: '>= aspnetcore-6.0' description: Overview of Single Page Apps (SPAs) in ASP.NET Core diff --git a/aspnetcore/fundamentals/metapackage-app.md b/aspnetcore/fundamentals/metapackage-app.md index e8e0982f0357..c23925cf55da 100644 --- a/aspnetcore/fundamentals/metapackage-app.md +++ b/aspnetcore/fundamentals/metapackage-app.md @@ -1,6 +1,6 @@ --- title: Microsoft.AspNetCore.App metapackage for ASP.NET Core -author: Rick-Anderson +author: wadepickett description: The Microsoft.AspNetCore.App shared framework monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/fundamentals/minimal-apis.md b/aspnetcore/fundamentals/minimal-apis.md index 82d842e85ffd..1bc805a019e9 100644 --- a/aspnetcore/fundamentals/minimal-apis.md +++ b/aspnetcore/fundamentals/minimal-apis.md @@ -1,6 +1,6 @@ --- title: Minimal APIs quick reference -author: rick-anderson +author: wadepickett description: Provides an overview of minimal APIs in ASP.NET Core ms.author: wpickett content_well_notification: AI-contribution diff --git a/aspnetcore/fundamentals/minimal-apis/min-api-filters.md b/aspnetcore/fundamentals/minimal-apis/min-api-filters.md index 234559900d68..5fce6b8e867d 100644 --- a/aspnetcore/fundamentals/minimal-apis/min-api-filters.md +++ b/aspnetcore/fundamentals/minimal-apis/min-api-filters.md @@ -1,6 +1,6 @@ --- title: Filters in Minimal API apps -author: rick-anderson +author: wadepickett description: Use filters in Minimal API apps ms.author: wpickett ms.date: 8/11/2022 diff --git a/aspnetcore/fundamentals/minimal-apis/parameter-binding.md b/aspnetcore/fundamentals/minimal-apis/parameter-binding.md index aa1d59f2f278..1f4f5d66f8ac 100644 --- a/aspnetcore/fundamentals/minimal-apis/parameter-binding.md +++ b/aspnetcore/fundamentals/minimal-apis/parameter-binding.md @@ -1,6 +1,6 @@ --- title: Parameter binding in Minimal API applications -author: rick-anderson +author: wadepickett description: Learn how parameters are populated before invoking minimal route handlers. ms.author: wpickett monikerRange: '>= aspnetcore-7.0' diff --git a/aspnetcore/fundamentals/minimal-apis/route-handlers.md b/aspnetcore/fundamentals/minimal-apis/route-handlers.md index 66aac8d394f0..bf33e64e501d 100644 --- a/aspnetcore/fundamentals/minimal-apis/route-handlers.md +++ b/aspnetcore/fundamentals/minimal-apis/route-handlers.md @@ -1,6 +1,6 @@ --- title: Route handlers in Minimal API apps -author: rick-anderson +author: wadepickett description: Learn how to handle requests in Minimal API apps. ms.author: wpickett monikerRange: '>= aspnetcore-7.0' diff --git a/aspnetcore/fundamentals/minimal-apis/test-min-api.md b/aspnetcore/fundamentals/minimal-apis/test-min-api.md index 02f844677c65..bce516f6589e 100644 --- a/aspnetcore/fundamentals/minimal-apis/test-min-api.md +++ b/aspnetcore/fundamentals/minimal-apis/test-min-api.md @@ -1,6 +1,6 @@ --- title: Test Minimal API apps -author: rick-anderson +author: wadepickett description: Unit and integration tests in Minimal API apps ms.author: wpickett ms.date: 05/31/2024 diff --git a/aspnetcore/fundamentals/minimal-apis/webapplication.md b/aspnetcore/fundamentals/minimal-apis/webapplication.md index 090b7503525c..fa64b33c7daf 100644 --- a/aspnetcore/fundamentals/minimal-apis/webapplication.md +++ b/aspnetcore/fundamentals/minimal-apis/webapplication.md @@ -1,6 +1,6 @@ --- title: WebApplication and WebApplicationBuilder in Minimal API apps -author: rick-anderson +author: wadepickett description: Learn about how to use WebApplication and WebApplicationBuilder. ms.author: wpickett monikerRange: '>= aspnetcore-7.0' diff --git a/aspnetcore/fundamentals/openapi/overview.md b/aspnetcore/fundamentals/openapi/overview.md index 96293769670d..1d29aa90234f 100644 --- a/aspnetcore/fundamentals/openapi/overview.md +++ b/aspnetcore/fundamentals/openapi/overview.md @@ -1,6 +1,6 @@ --- title: Overview of OpenAPI support in ASP.NET Core API apps -author: rick-anderson +author: wadepickett description: Learn about OpenAPI features in ASP.NET Core. ms.author: wpickett monikerRange: '>= aspnetcore-6.0' diff --git a/aspnetcore/fundamentals/startup.md b/aspnetcore/fundamentals/startup.md index fddb13f336a8..7be0034ce5d3 100644 --- a/aspnetcore/fundamentals/startup.md +++ b/aspnetcore/fundamentals/startup.md @@ -1,6 +1,6 @@ --- title: App startup in ASP.NET Core -author: rick-anderson +author: wadepickett description: Learn how the Startup class in ASP.NET Core configures services and the app's request pipeline. monikerRange: '>= aspnetcore-3.1' ms.author: wpickett diff --git a/aspnetcore/fundamentals/target-aspnetcore.md b/aspnetcore/fundamentals/target-aspnetcore.md index d9c7bdc87658..bb2ff5aff7f4 100644 --- a/aspnetcore/fundamentals/target-aspnetcore.md +++ b/aspnetcore/fundamentals/target-aspnetcore.md @@ -1,6 +1,6 @@ --- title: Use ASP.NET Core APIs in a class library -author: rick-anderson +author: wadepickett description: Learn how to use ASP.NET Core APIs in a class library. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/host-and-deploy/azure-apps/index.md b/aspnetcore/host-and-deploy/azure-apps/index.md index 3dce797bae26..3b04306483f0 100644 --- a/aspnetcore/host-and-deploy/azure-apps/index.md +++ b/aspnetcore/host-and-deploy/azure-apps/index.md @@ -1,6 +1,6 @@ --- title: Deploy ASP.NET Core apps to Azure App Service -author: bradygaster +author: wadepickett description: This article contains links to Azure host and deploy resources. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/host-and-deploy/docker/building-net-docker-images.md b/aspnetcore/host-and-deploy/docker/building-net-docker-images.md index 282bb63bd3a5..a5e8be2d76e7 100644 --- a/aspnetcore/host-and-deploy/docker/building-net-docker-images.md +++ b/aspnetcore/host-and-deploy/docker/building-net-docker-images.md @@ -1,6 +1,6 @@ --- title: Run an ASP.NET Core app in Docker containers -author: rick-anderson +author: wadepickett description: Learn how to use the published ASP.NET Core Docker images from the Docker Registry. Pull and build your own images. ms.author: wpickett ms.custom: mvc, linux-related-content diff --git a/aspnetcore/host-and-deploy/docker/index.md b/aspnetcore/host-and-deploy/docker/index.md index 024b849bfd02..903191844f8e 100644 --- a/aspnetcore/host-and-deploy/docker/index.md +++ b/aspnetcore/host-and-deploy/docker/index.md @@ -1,6 +1,6 @@ --- title: Host ASP.NET Core in Docker containers -author: rick-anderson +author: wadepickett description: Discover links to resources for learning how to host ASP.NET Core apps in Docker containers. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/index.yml b/aspnetcore/index.yml index 775e77c3cf4f..11b84cb9a03f 100644 --- a/aspnetcore/index.yml +++ b/aspnetcore/index.yml @@ -9,7 +9,7 @@ metadata: description: Learn to use ASP.NET Core to create web apps and services that are fast, secure, cross-platform, and cloud-based. Browse tutorials, sample code, fundamentals, API reference and more. ms.product: aspnet ms.topic: hub-page - author: WadePickett + author: wadepickett ms.author: wpickett ms.date: 02/23/2024 diff --git a/aspnetcore/migration/1x-to-2x/identity-2x.md b/aspnetcore/migration/1x-to-2x/identity-2x.md index 930d736d589a..b34a220c3b63 100644 --- a/aspnetcore/migration/1x-to-2x/identity-2x.md +++ b/aspnetcore/migration/1x-to-2x/identity-2x.md @@ -1,6 +1,6 @@ --- title: Migrate authentication and Identity to ASP.NET Core 2.0 -author: rick-anderson +author: wadepickett description: This article outlines the most common steps for migrating ASP.NET Core 1.x authentication and Identity to ASP.NET Core 2.0. ms.author: wpickett ms.date: 06/21/2019 diff --git a/aspnetcore/migration/1x-to-2x/index.md b/aspnetcore/migration/1x-to-2x/index.md index 2fbcebfeba2d..aa92ca35c5b3 100644 --- a/aspnetcore/migration/1x-to-2x/index.md +++ b/aspnetcore/migration/1x-to-2x/index.md @@ -1,6 +1,6 @@ --- title: Migrate from ASP.NET Core 1.x to 2.0 -author: rick-anderson +author: wadepickett description: This article outlines the prerequisites and most common steps for migrating an ASP.NET Core 1.x project to ASP.NET Core 2.0. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/migration/21-to-22.md b/aspnetcore/migration/21-to-22.md index 22ced5783345..9402284f11a5 100644 --- a/aspnetcore/migration/21-to-22.md +++ b/aspnetcore/migration/21-to-22.md @@ -1,6 +1,6 @@ --- title: Migrate from ASP.NET Core 2.1 to 2.2 -author: rick-anderson +author: wadepickett description: This article outlines the prerequisites and most common steps for migrating an ASP.NET Core 2.1 project to ASP.NET Core 2.2. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/migration/30-to-31.md b/aspnetcore/migration/30-to-31.md index d56169d503ae..77d51c2d2623 100644 --- a/aspnetcore/migration/30-to-31.md +++ b/aspnetcore/migration/30-to-31.md @@ -1,6 +1,6 @@ --- title: Migrate from ASP.NET Core 3.0 to 3.1 -author: rick-anderson +author: wadepickett description: Learn how to migrate an ASP.NET Core 3.0 project to ASP.NET Core 3.1. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/migration/31-to-50.md b/aspnetcore/migration/31-to-50.md index e2c362d50c1a..a220e36e7700 100644 --- a/aspnetcore/migration/31-to-50.md +++ b/aspnetcore/migration/31-to-50.md @@ -1,6 +1,6 @@ --- title: Migrate from ASP.NET Core 3.1 to 5.0 -author: rick-anderson +author: wadepickett description: Learn how to migrate an ASP.NET Core 3.1 project to ASP.NET Core 5.0. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/mvc/views/tag-helpers/built-in/partial-tag-helper.md b/aspnetcore/mvc/views/tag-helpers/built-in/partial-tag-helper.md index 9ef70928d8f5..2770794675e7 100644 --- a/aspnetcore/mvc/views/tag-helpers/built-in/partial-tag-helper.md +++ b/aspnetcore/mvc/views/tag-helpers/built-in/partial-tag-helper.md @@ -1,6 +1,6 @@ --- title: Partial Tag Helper in ASP.NET Core -author: rick-anderson +author: wadepickett description: Discover the ASP.NET Core Partial Tag Helper and the role each of its attributes play in rendering a partial view. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/mvc/views/tag-helpers/th-components.md b/aspnetcore/mvc/views/tag-helpers/th-components.md index d53d00660ba6..99dcded1b9c9 100644 --- a/aspnetcore/mvc/views/tag-helpers/th-components.md +++ b/aspnetcore/mvc/views/tag-helpers/th-components.md @@ -1,6 +1,6 @@ --- title: Tag Helper Components in ASP.NET Core -author: rick-anderson +author: wadepickett description: Learn what Tag Helper Components are and how to use them in ASP.NET Core. monikerRange: '>= aspnetcore-2.0' ms.author: wpickett diff --git a/aspnetcore/security/authorization/resourcebased.md b/aspnetcore/security/authorization/resourcebased.md index 118f021d50c0..ad15ca5c3c93 100644 --- a/aspnetcore/security/authorization/resourcebased.md +++ b/aspnetcore/security/authorization/resourcebased.md @@ -1,6 +1,6 @@ --- title: Resource-based authorization in ASP.NET Core -author: rick-anderson +author: wadepickett description: Learn how to implement resource-based authorization in an ASP.NET Core app when an Authorize attribute won't suffice. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/security/docker-https.md b/aspnetcore/security/docker-https.md index bc768c4e522a..f89cc65100f8 100644 --- a/aspnetcore/security/docker-https.md +++ b/aspnetcore/security/docker-https.md @@ -1,6 +1,6 @@ --- title: Hosting ASP.NET Core Images with Docker over HTTPS -author: rick-anderson +author: wadepickett description: Learn how to host ASP.NET Core Images with Docker over HTTPS ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/signalr/api-design.md b/aspnetcore/signalr/api-design.md index 248664e55a9b..cbcdc600315a 100644 --- a/aspnetcore/signalr/api-design.md +++ b/aspnetcore/signalr/api-design.md @@ -1,6 +1,6 @@ --- title: SignalR API design considerations -author: bradygaster +author: wadepickett description: Learn how to design SignalR APIs for compatibility across versions of your app. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/authn-and-authz.md b/aspnetcore/signalr/authn-and-authz.md index 21f64037b60d..9cb9900edf20 100644 --- a/aspnetcore/signalr/authn-and-authz.md +++ b/aspnetcore/signalr/authn-and-authz.md @@ -1,6 +1,6 @@ --- title: Authentication and authorization in ASP.NET Core SignalR -author: bradygaster +author: wadepickett description: Learn how to use authentication and authorization in ASP.NET Core SignalR. monikerRange: '>= aspnetcore-3.1' ms.author: wpickett diff --git a/aspnetcore/signalr/background-services.md b/aspnetcore/signalr/background-services.md index b79dc56d08ad..1c4e1b56f897 100644 --- a/aspnetcore/signalr/background-services.md +++ b/aspnetcore/signalr/background-services.md @@ -1,6 +1,6 @@ --- title: Host ASP.NET Core SignalR in background services -author: bradygaster +author: wadepickett description: Learn how to send messages to SignalR clients from .NET Core BackgroundService classes. monikerRange: '>= aspnetcore-2.2' ms.author: wpickett diff --git a/aspnetcore/signalr/client-features.md b/aspnetcore/signalr/client-features.md index c10339052167..fa24a1628eae 100644 --- a/aspnetcore/signalr/client-features.md +++ b/aspnetcore/signalr/client-features.md @@ -1,6 +1,6 @@ --- title: ASP.NET Core SignalR clients -author: bradygaster +author: wadepickett description: Learn which features are supported by the various ASP.NET Core SignalR clients. ms.author: wpickett ms.custom: mvc diff --git a/aspnetcore/signalr/configuration.md b/aspnetcore/signalr/configuration.md index b272b6e3d7ba..2110d6dfd7ca 100644 --- a/aspnetcore/signalr/configuration.md +++ b/aspnetcore/signalr/configuration.md @@ -1,6 +1,6 @@ --- title: ASP.NET Core SignalR configuration -author: bradygaster +author: wadepickett description: Learn how to configure ASP.NET Core SignalR apps. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/diagnostics.md b/aspnetcore/signalr/diagnostics.md index c18d5390cb7d..1c5de533e5c8 100644 --- a/aspnetcore/signalr/diagnostics.md +++ b/aspnetcore/signalr/diagnostics.md @@ -1,6 +1,6 @@ --- title: Logging and diagnostics in ASP.NET Core SignalR -author: wpickett +author: wadepickett description: Learn how to gather diagnostics from your ASP.NET Core SignalR app. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/dotnet-client.md b/aspnetcore/signalr/dotnet-client.md index fec34200767d..c436d94298f5 100644 --- a/aspnetcore/signalr/dotnet-client.md +++ b/aspnetcore/signalr/dotnet-client.md @@ -1,6 +1,6 @@ --- title: ASP.NET Core SignalR .NET Client -author: bradygaster +author: wadepickett description: Information about the ASP.NET Core SignalR .NET Client monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/groups.md b/aspnetcore/signalr/groups.md index e6eb5e3dcb1c..2aaf429baa7f 100644 --- a/aspnetcore/signalr/groups.md +++ b/aspnetcore/signalr/groups.md @@ -1,6 +1,6 @@ --- title: Manage users and groups in SignalR -author: bradygaster +author: wadepickett description: Overview of ASP.NET Core SignalR User and Group management. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/hubcontext.md b/aspnetcore/signalr/hubcontext.md index 47d9a8cbf404..7a255a7a92ac 100644 --- a/aspnetcore/signalr/hubcontext.md +++ b/aspnetcore/signalr/hubcontext.md @@ -1,6 +1,6 @@ --- title: SignalR HubContext -author: bradygaster +author: wadepickett description: Learn how to use the ASP.NET Core SignalR HubContext service for sending notifications to clients from outside a hub. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/hubs.md b/aspnetcore/signalr/hubs.md index 06fc91394283..cd5fcc77269e 100644 --- a/aspnetcore/signalr/hubs.md +++ b/aspnetcore/signalr/hubs.md @@ -1,6 +1,6 @@ --- title: Use hubs in ASP.NET Core SignalR -author: bradygaster +author: wadepickett description: Learn how to use hubs in ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/introduction.md b/aspnetcore/signalr/introduction.md index c9a6373e9037..8f18f9ff5669 100644 --- a/aspnetcore/signalr/introduction.md +++ b/aspnetcore/signalr/introduction.md @@ -1,6 +1,6 @@ --- title: Overview of ASP.NET Core SignalR -author: wpickett +author: wadepickett description: Learn how the ASP.NET Core SignalR library simplifies adding real-time functionality to apps. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/javascript-client.md b/aspnetcore/signalr/javascript-client.md index eedfa455a5e0..c6afc8cfe01a 100644 --- a/aspnetcore/signalr/javascript-client.md +++ b/aspnetcore/signalr/javascript-client.md @@ -1,6 +1,6 @@ --- title: ASP.NET Core SignalR JavaScript client -author: bradygaster +author: wadepickett description: Overview of ASP.NET Core SignalR JavaScript client. monikerRange: '>= aspnetcore-3.1' ms.author: wpickett diff --git a/aspnetcore/signalr/messagepackhubprotocol.md b/aspnetcore/signalr/messagepackhubprotocol.md index f802445c38d1..2adb2aa2d983 100644 --- a/aspnetcore/signalr/messagepackhubprotocol.md +++ b/aspnetcore/signalr/messagepackhubprotocol.md @@ -1,6 +1,6 @@ --- title: Use MessagePack Hub Protocol in SignalR for ASP.NET Core -author: bradygaster +author: wadepickett description: Add MessagePack Hub Protocol to ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/publish-to-azure-web-app.md b/aspnetcore/signalr/publish-to-azure-web-app.md index 3ce161248dc9..4f299cb58f88 100644 --- a/aspnetcore/signalr/publish-to-azure-web-app.md +++ b/aspnetcore/signalr/publish-to-azure-web-app.md @@ -1,6 +1,6 @@ --- title: Publish an ASP.NET Core SignalR app to Azure App Service -author: bradygaster +author: wadepickett description: Learn how to publish an ASP.NET Core SignalR app to Azure App Service. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/redis-backplane.md b/aspnetcore/signalr/redis-backplane.md index 66d7ece744d6..9a866b18fd00 100644 --- a/aspnetcore/signalr/redis-backplane.md +++ b/aspnetcore/signalr/redis-backplane.md @@ -1,6 +1,6 @@ --- title: Redis backplane for ASP.NET Core SignalR scale-out -author: bradygaster +author: wadepickett description: Learn how to set up a Redis backplane to enable scale-out for an ASP.NET Core SignalR app. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/scale.md b/aspnetcore/signalr/scale.md index f1b9e290d178..f73c12dad54d 100644 --- a/aspnetcore/signalr/scale.md +++ b/aspnetcore/signalr/scale.md @@ -1,6 +1,6 @@ --- title: ASP.NET Core SignalR production hosting and scaling -author: bradygaster +author: wadepickett description: Learn how to avoid performance and scaling problems in apps that use ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/security.md b/aspnetcore/signalr/security.md index b627cb30fd35..ff9e3fc1004e 100644 --- a/aspnetcore/signalr/security.md +++ b/aspnetcore/signalr/security.md @@ -1,6 +1,6 @@ --- title: Security considerations in ASP.NET Core SignalR -author: bradygaster +author: wadepickett description: Learn about security in ASP.NET Core SignalR. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/streaming.md b/aspnetcore/signalr/streaming.md index b9af3142e1e9..f1e537e25a76 100644 --- a/aspnetcore/signalr/streaming.md +++ b/aspnetcore/signalr/streaming.md @@ -1,6 +1,6 @@ --- title: Use streaming in ASP.NET Core SignalR -author: bradygaster +author: wadepickett description: Learn how to stream data between the client and the server. monikerRange: '>= aspnetcore-3.1' ms.author: wpickett diff --git a/aspnetcore/signalr/supported-platforms.md b/aspnetcore/signalr/supported-platforms.md index 935354c0b059..d6a6de6cfe6e 100644 --- a/aspnetcore/signalr/supported-platforms.md +++ b/aspnetcore/signalr/supported-platforms.md @@ -1,6 +1,6 @@ --- title: ASP.NET Core SignalR supported platforms -author: bradygaster +author: wadepickett description: Learn about the supported platforms for ASP.NET Core SignalR. monikerRange: '>= aspnetcore-3.1' ms.author: wpickett diff --git a/aspnetcore/signalr/troubleshoot.md b/aspnetcore/signalr/troubleshoot.md index 45963cf2cc33..70c526d5c66c 100644 --- a/aspnetcore/signalr/troubleshoot.md +++ b/aspnetcore/signalr/troubleshoot.md @@ -1,6 +1,6 @@ --- title: ASP.NET Core SignalR connection troubleshooting -author: bradygaster +author: wadepickett description: ASP.NET Core SignalR connection troubleshooting. monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/signalr/version-differences.md b/aspnetcore/signalr/version-differences.md index b4bf1a9f3588..4d0050dae4ff 100644 --- a/aspnetcore/signalr/version-differences.md +++ b/aspnetcore/signalr/version-differences.md @@ -1,6 +1,6 @@ --- title: Differences between SignalR and ASP.NET Core SignalR -author: bradygaster +author: wadepickett description: Differences between SignalR and ASP.NET Core SignalR monikerRange: '>= aspnetcore-2.1' ms.author: wpickett diff --git a/aspnetcore/test/debug-aspnetcore-source.md b/aspnetcore/test/debug-aspnetcore-source.md index e58106e47134..ec64871cb08d 100644 --- a/aspnetcore/test/debug-aspnetcore-source.md +++ b/aspnetcore/test/debug-aspnetcore-source.md @@ -1,6 +1,6 @@ --- title: Debug .NET and ASP.NET Core source code with Visual Studio -author: rick-anderson +author: wadepickett description: Debug .NET and ASP.NET Core source code with Visual Studio monikerRange: '>= aspnetcore-3.1' ms.author: wpickett diff --git a/aspnetcore/tutorials/signalr.md b/aspnetcore/tutorials/signalr.md index ebeb252265c6..23a81418097b 100644 --- a/aspnetcore/tutorials/signalr.md +++ b/aspnetcore/tutorials/signalr.md @@ -1,6 +1,6 @@ --- title: Get started with ASP.NET Core SignalR -author: bradygaster +author: wadepickett description: In this tutorial, you create a chat app that uses ASP.NET Core SignalR. ms.author: wpickett From 4659d93fbe4464f6cae122116dbb579dfb35d5e7 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Mon, 5 May 2025 10:29:03 -0400 Subject: [PATCH 11/15] Statically-rendered layout components (#35344) --- .../blazor/components/built-in-components.md | 12 +-- aspnetcore/blazor/components/layouts.md | 88 +++++++++++++++++-- aspnetcore/blazor/components/render-modes.md | 5 ++ 3 files changed, 94 insertions(+), 11 deletions(-) diff --git a/aspnetcore/blazor/components/built-in-components.md b/aspnetcore/blazor/components/built-in-components.md index 05470eb88d2e..c86fec34c08c 100644 --- a/aspnetcore/blazor/components/built-in-components.md +++ b/aspnetcore/blazor/components/built-in-components.md @@ -37,7 +37,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo * [`InputSelect`](xref:blazor/forms/input-components) * [`InputText`](xref:blazor/forms/input-components) * [`InputTextArea`](xref:blazor/forms/input-components) -* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components) +* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component) * [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component) * [`NavigationLock`](xref:blazor/fundamentals/routing#handleprevent-location-changes) * [`NavLink`](xref:blazor/fundamentals/routing#navlink-component) @@ -77,7 +77,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo * [`InputSelect`](xref:blazor/forms/input-components) * [`InputText`](xref:blazor/forms/input-components) * [`InputTextArea`](xref:blazor/forms/input-components) -* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components) +* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component) * [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component) * [`NavigationLock`](xref:blazor/fundamentals/routing#handleprevent-location-changes) * [`NavLink`](xref:blazor/fundamentals/routing#navlink-component) @@ -115,7 +115,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo * [`InputSelect`](xref:blazor/forms/input-components) * [`InputText`](xref:blazor/forms/input-components) * [`InputTextArea`](xref:blazor/forms/input-components) -* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components) +* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component) * [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component) * [`NavigationLock`](xref:blazor/fundamentals/routing#handleprevent-location-changes) * [`NavLink`](xref:blazor/fundamentals/routing#navlink-component) @@ -149,7 +149,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo * [`InputSelect`](xref:blazor/forms/input-components) * [`InputText`](xref:blazor/forms/input-components) * [`InputTextArea`](xref:blazor/forms/input-components) -* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components) +* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component) * [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component) * [`NavLink`](xref:blazor/fundamentals/routing#navlink-component) * [`OwningComponentBase`](xref:fundamentals/dependency-injection#utility-base-component-classes-to-manage-a-di-scope) @@ -177,7 +177,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo * [`InputSelect`](xref:blazor/forms/input-components) * [`InputText`](xref:blazor/forms/input-components) * [`InputTextArea`](xref:blazor/forms/input-components) -* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components) +* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component) * [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component) * [`NavLink`](xref:blazor/fundamentals/routing#navlink-component) * [`OwningComponentBase`](xref:fundamentals/dependency-injection#utility-base-component-classes-to-manage-a-di-scope) @@ -203,7 +203,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo * [`InputSelect`](xref:blazor/forms/input-components) * [`InputText`](xref:blazor/forms/input-components) * [`InputTextArea`](xref:blazor/forms/input-components) -* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components) +* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component) * [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component) * [`NavLink`](xref:blazor/fundamentals/routing#navlink-component) * [`OwningComponentBase`](xref:fundamentals/dependency-injection#utility-base-component-classes-to-manage-a-di-scope) diff --git a/aspnetcore/blazor/components/layouts.md b/aspnetcore/blazor/components/layouts.md index 3e39a46aed2b..1841b157ac78 100644 --- a/aspnetcore/blazor/components/layouts.md +++ b/aspnetcore/blazor/components/layouts.md @@ -20,9 +20,7 @@ Some app elements, such as menus, copyright messages, and company logos, are usu A Blazor layout is a Razor component that shares markup with components that reference it. Layouts can use [data binding](xref:blazor/components/data-binding), [dependency injection](xref:blazor/fundamentals/dependency-injection), and other features of components. -## Layout components - -### Create a layout component +## Create a layout component To create a layout component: @@ -73,7 +71,7 @@ The following `DoctorWhoLayout` component shows the Razor template of a layout c :::moniker-end -### `MainLayout` component +## `MainLayout` component In an app created from a [Blazor project template](xref:blazor/project-structure), the `MainLayout` component is the app's [default layout](#apply-a-default-layout-to-an-app). Blazor's layout adopts the [:::no-loc text="Flexbox"::: layout model](https://developer.mozilla.org/docs/Glossary/Flexbox) ([W3C specification](https://www.w3.org/TR/css-flexbox-1/)). @@ -94,6 +92,86 @@ In an app created from a [Blazor project template](xref:blazor/project-structure :::moniker-end +:::moniker range=">= aspnetcore-8.0" + + + +## Statically-rendered layout components + +When a Blazor Web App adopts per-page/component rendering (the `Routes` component doesn't specify an interactive render mode), layout components are rendered statically on the server. Applying an interactive render mode directly to a layout isn't supported because Blazor doesn't support serializing a (`@Body` in this case) as a root component parameter. For example, placing `@rendermode InteractiveServer` at the top of the `MainLayout` component results in the following runtime exception: + +> :::no-loc text="System.InvalidOperationException: Cannot pass the parameter 'Body' to component 'MainLayout' with rendermode 'InteractiveServerRenderMode'. This is because the parameter is of the delegate type 'Microsoft.AspNetCore.Components.RenderFragment', which is arbitrary code and cannot be serialized."::: + +This applies to any layout component that inherits from in an app that adopts per-page/component rendering. + +This scenario might be addressed in a future release of Blazor. For more information, see [[Blazor] Support serializing render fragments from SSR (`dotnet/aspnetcore` #52768)](https://github.com/dotnet/aspnetcore/issues/52768). In the meantime, you can adopt the following approach in a Blazor Web App that adopts per-page/component rendering. + +Create a wrapper component that's capable of interactivity. In the following example, a wrapper component contains a [Blazor section](xref:blazor/components/sections) that can receive content from a child component. + +In the `_Imports.razor` file, add an [`@using`](xref:mvc/views/razor#using) directive for sections (): + +```razor +@using Microsoft.AspNetCore.Components.Sections +``` + +Create the following interactive wrapper component in the `Pages` folder. + +`Pages/InteractiveWrapper.razor`: + +```razor +@rendermode InteractiveServer + +
+ +
+ +@ChildContent + +@code { + [Parameter] + public RenderFragment? ChildContent { get; set; } +} +``` + +The `Counter` component can use the wrapper component and set interactive section content. In the following example, a counter button is placed in the section. + +`Pages/Counter.razor`: + +```razor +@page "/counter" +@rendermode InteractiveServer + + + + + + + + Counter + +

Counter

+ +

Current count: @currentCount

+ + + +
+ +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } +} +``` + +Other components around the app can also wrap content in the `InteractiveWrapper` component and set interactive section content. + +:::moniker-end + ## Apply a layout ### Make the layout namespace available @@ -220,7 +298,7 @@ Specify the default app layout in the ``` -In the preceding example, the `{LAYOUT}` placeholder is the layout (for example, `DoctorWhoLayout` if the layout file name is `DoctorWhoLayout.razor`). You may need to idenfity the layout's namespace depending on the .NET version and type of Blazor app. For more information, see the [Make the layout namespace available](#make-the-layout-namespace-available) section. +In the preceding example, the `{LAYOUT}` placeholder is the layout (for example, `DoctorWhoLayout` if the layout file name is `DoctorWhoLayout.razor`). You may need to identify the layout's namespace depending on the .NET version and type of Blazor app. For more information, see the [Make the layout namespace available](#make-the-layout-namespace-available) section. Specifying the layout as a default layout in the component's is a useful practice because you can override the layout on a per-component or per-folder basis, as described in the preceding sections of this article. We recommend using the component to set the app's default layout because it's the most general and flexible approach for using layouts. diff --git a/aspnetcore/blazor/components/render-modes.md b/aspnetcore/blazor/components/render-modes.md index 38d23bf0364a..c4daeef0cc5e 100644 --- a/aspnetcore/blazor/components/render-modes.md +++ b/aspnetcore/blazor/components/render-modes.md @@ -576,6 +576,11 @@ Non-serializable component parameters, such as child content or a render fragmen > :::no-loc text="System.InvalidOperationException: Cannot pass the parameter 'ChildContent' to component 'SharedMessage' with rendermode 'InteractiveServerRenderMode'. This is because the parameter is of the delegate type 'Microsoft.AspNetCore.Components.RenderFragment', which is arbitrary code and cannot be serialized."::: + + +The same thing happens if you attempt to adopt interactive rendering in a layout that inherits from , such as the app's `MainLayout` component, in an app that adopts per-page/component rendering. For more information, see . + To circumvent the preceding limitation, wrap the child component in another component that doesn't have the parameter. This is the approach taken in the Blazor Web App project template with the `Routes` component (`Components/Routes.razor`) to wrap the component. `WrapperComponent.razor`: From 2b3283b5d780a2f342b44917d1f976d06241f171 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Mon, 5 May 2025 10:43:11 -0400 Subject: [PATCH 12/15] Cross-link Sections article to new content (#35345) --- aspnetcore/blazor/components/sections.md | 1 + 1 file changed, 1 insertion(+) diff --git a/aspnetcore/blazor/components/sections.md b/aspnetcore/blazor/components/sections.md index 7283c0cb89c5..6a1fca94cdb1 100644 --- a/aspnetcore/blazor/components/sections.md +++ b/aspnetcore/blazor/components/sections.md @@ -92,3 +92,4 @@ A section interacts with other Blazor features in the following ways: * [Cascading values](xref:blazor/components/cascading-values-and-parameters) flow into section content from where the content is defined by the component. * Unhandled exceptions are handled by [error boundaries](xref:blazor/fundamentals/handle-errors#error-boundaries) defined around a component. * A Razor component configured for [streaming rendering](xref:blazor/components/rendering#streaming-rendering) also configures section content provided by a component to use streaming rendering. +* A section that contains interactive components is statically rendered (non-functional) in a layout component in a Blazor Web App that adopts per-page/component rendering. For more information, see . From 8e88a99f621e594b493660842bca952cc879c9c1 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Mon, 5 May 2025 11:40:01 -0400 Subject: [PATCH 13/15] Additional ServerWeatherForecaster scenarios (#35347) --- aspnetcore/blazor/call-web-api.md | 17 ++++++-- .../security/blazor-web-app-with-entra.md | 2 +- aspnetcore/blazor/security/index.md | 41 ++++++++++++++++++- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/aspnetcore/blazor/call-web-api.md b/aspnetcore/blazor/call-web-api.md index 0beae83a9cef..eab24ab47352 100644 --- a/aspnetcore/blazor/call-web-api.md +++ b/aspnetcore/blazor/call-web-api.md @@ -22,14 +22,25 @@ The [`System.Net.Http.Json`](https://www.nuget.org/packages/System.Net.Http.Json ## Use a token handler for web API calls -Blazor Web Apps with OIDC authentication can use a token handler approach to make outgoing requests to secure external web API calls. This approach is used by the `BlazorWebAppOidc` and `BlazorWebAppOidcServer` sample apps described in the next section. +Blazor Web Apps with OIDC authentication can use a token handler approach to make outgoing requests to secure external web API calls. This approach is used by the `BlazorWebAppOidc` and `BlazorWebAppOidcServer` sample apps described in the *Sample apps* section of this article. For more information, see the following resources: * * *Secure an ASP.NET Core Blazor Web App with OpenID Connect (OIDC)* - * [Non-BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-oidc?view=aspnetcore-9.0&pivots=non-bff-pattern) - * [Non-BFF pattern (Interactive Server)](xref:blazor/security/blazor-web-app-oidc?view=aspnetcore-9.0&pivots=non-bff-pattern-server) + * [Non-BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-oidc?pivots=non-bff-pattern) + * [Non-BFF pattern (Interactive Server)](xref:blazor/security/blazor-web-app-oidc?pivots=non-bff-pattern-server) + +## Microsoft identity platform for web API calls + +Blazor Web Apps that use use [Microsoft identity platform](/entra/identity-platform/)/[Microsoft Identity Web packages](/entra/msal/dotnet/microsoft-identity-web/) for [Microsoft Entra ID](https://www.microsoft.com/security/business/microsoft-entra) can make streamlined calls using Entra-specific API. This approach is used by the `BlazorWebAppEntra` and `BlazorWebAppEntraBff` sample apps described in the *Sample apps* section of this article. + +For more information, see the following resources: + +* +* *Secure an ASP.NET Core Blazor Web App with Microsoft Entra ID* + * [Non-BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-entra?pivots=non-bff-pattern) + * [BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-entra?pivots=non-bff-pattern-server) ## Sample apps diff --git a/aspnetcore/blazor/security/blazor-web-app-with-entra.md b/aspnetcore/blazor/security/blazor-web-app-with-entra.md index 8d8ec274a0dc..809804fedcac 100644 --- a/aspnetcore/blazor/security/blazor-web-app-with-entra.md +++ b/aspnetcore/blazor/security/blazor-web-app-with-entra.md @@ -30,7 +30,7 @@ The following specification is covered: * The app uses [Microsoft Entra ID](https://www.microsoft.com/security/business/microsoft-entra), based on [Microsoft Identity Web](/entra/msal/dotnet/microsoft-identity-web/) packages. * Automatic non-interactive token refresh is managed by the framework. * The app uses server-side and client-side service abstractions to display generated weather data: - * When rendering the `Weather` component on the server to display weather data, the component uses the `ServerWeatherForecaster` on the server to directly obtain weather data (not via a web API call). + * When rendering the `Weather` component on the server to display weather data, the component uses the `ServerWeatherForecaster` on the server to obtain weather data. * When the `Weather` component is rendered on the client, the component uses the `ClientWeatherForecaster` service implementation, which uses a preconfigured (in the client project's `Program` file) to make a web API call to the server project's Minimal API (`/weather-forecast`) for weather data. The Minimal API endpoint obtains the weather data from the `ServerWeatherForecaster` class and returns it to the client for rendering by the component. ## Sample solution diff --git a/aspnetcore/blazor/security/index.md b/aspnetcore/blazor/security/index.md index ff89ffc55471..5b1f5427701f 100644 --- a/aspnetcore/blazor/security/index.md +++ b/aspnetcore/blazor/security/index.md @@ -772,7 +772,7 @@ else The server project implements `IWeatherForecaster` as `ServerWeatherForecaster`, which generates and returns mock weather data via its `GetWeatherForecastAsync` method: ```csharp -public class ServerWeatherForecaster() : IWeatherForecaster +internal sealed class ServerWeatherForecaster() : IWeatherForecaster { public readonly string[] summaries = [ @@ -797,6 +797,45 @@ public class ServerWeatherForecaster() : IWeatherForecaster } ``` +Alternatively, the `ServerWeatherForecaster` can call an external web API using a [named HTTP Client and token handler approach](xref:blazor/call-web-api#use-a-token-handler-for-web-API-calls), as the following example demonstrates: + +```csharp +internal sealed class ServerWeatherForecaster(IHttpClientFactory clientFactory) : IWeatherForecaster +{ + public async Task> GetWeatherForecastAsync() + { + var request = new HttpRequestMessage(HttpMethod.Get, "/weather-forecast"); + var client = clientFactory.CreateClient("ExternalApi"); + + var response = await client.SendAsync(request); + + response.EnsureSuccessStatusCode(); + + return await response.Content.ReadFromJsonAsync() ?? + throw new IOException("No weather forecast!"); + } +} +``` + +If the app uses [Microsoft identity platform](/entra/identity-platform/)/[Microsoft Identity Web packages](/entra/msal/dotnet/microsoft-identity-web/) for [Microsoft Entra ID](https://www.microsoft.com/security/business/microsoft-entra) (see ), the `ServerWeatherForecaster` might appear like the following class to make external web API calls: + +```csharp +internal sealed class ServerWeatherForecaster(IDownstreamApi downstreamApi) : IWeatherForecaster +{ + public async Task> GetWeatherForecastAsync() + { + var response = await downstreamApi.CallApiForUserAsync("DownstreamApi", + options => + { + options.RelativePath = "/weather-forecast"; + }); + + return await response.Content.ReadFromJsonAsync() ?? + throw new IOException("No weather forecast!"); + } +} +``` + The server project maintains a secure web API endpoint for client weather data calls: ```csharp From 8dd431a621e41a55c4d257816d14a354ee0b386f Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Mon, 5 May 2025 11:55:52 -0400 Subject: [PATCH 14/15] Improve async void guidance (#35348) --- aspnetcore/blazor/components/event-handling.md | 3 +++ aspnetcore/blazor/components/index.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/aspnetcore/blazor/components/event-handling.md b/aspnetcore/blazor/components/event-handling.md index 20aef0c16755..b58d31129c4f 100644 --- a/aspnetcore/blazor/components/event-handling.md +++ b/aspnetcore/blazor/components/event-handling.md @@ -40,6 +40,9 @@ For event handling: :::moniker-end +> [!IMPORTANT] +> The Blazor framework doesn't track `void`-returning asynchronous methods (`async`). As a result, the entire process fails when an exception isn't caught if `void` is returned. Always return a / from asynchronous methods. + The following code: * Calls the `UpdateHeading` method when the button is selected in the UI. diff --git a/aspnetcore/blazor/components/index.md b/aspnetcore/blazor/components/index.md index 79319ee4c515..4a10bde23119 100644 --- a/aspnetcore/blazor/components/index.md +++ b/aspnetcore/blazor/components/index.md @@ -638,7 +638,7 @@ Razor syntax for C# control structures, directives, and directive attributes are ### Asynchronous methods (`async`) don't support returning `void` -The Blazor framework doesn't track `void`-returning asynchronous methods (`async`). As a result, exceptions aren't caught if `void` is returned. Always return a from asynchronous methods. +The Blazor framework doesn't track `void`-returning asynchronous methods (`async`). As a result, the entire process fails when an exception isn't caught if `void` is returned. Always return a / from asynchronous methods. ### Nested components From 781c7b1efb8603a2b7508600bfd4e87bd1732625 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Mon, 5 May 2025 12:22:00 -0400 Subject: [PATCH 15/15] Standalone WASM with IIS cross-links and content (#35351) --- aspnetcore/blazor/host-and-deploy/index.md | 4 ++-- .../host-and-deploy/webassembly/azure-static-web-apps.md | 8 ++++---- .../blazor/host-and-deploy/webassembly/azure-storage.md | 8 ++++---- .../blazor/host-and-deploy/webassembly/github-pages.md | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/aspnetcore/blazor/host-and-deploy/index.md b/aspnetcore/blazor/host-and-deploy/index.md index d85fb9221f0e..b98b401cb769 100644 --- a/aspnetcore/blazor/host-and-deploy/index.md +++ b/aspnetcore/blazor/host-and-deploy/index.md @@ -68,8 +68,8 @@ To host a Blazor app in IIS, see the following resources: * IIS hosting * * -* : Server apps running on IIS, including IIS with Azure Virtual Machines (VMs) running Windows OS and Azure App Service. -* : Includes additional guidance for Blazor WebAssembly apps hosted on IIS, including static site hosting, custom `web.config` files, URL rewriting, sub-apps, compression, and Azure Storage static file hosting. +* : Blazor Web Apps (.NET 8 or later) and Blazor Server apps (.NET 7 or earlier) running on IIS, including IIS with Azure Virtual Machines (VMs) running Windows OS and Azure App Service. +* : Standalone Blazor WebAssembly apps (all .NET releases) and hosted Blazor WebAssembly apps (.NET 7 or earlier). * IIS sub-application hosting * Follow the [app base path guidance](xref:blazor/host-and-deploy/app-base-path) prior to publishing the app. The examples use an app base path of `/CoolApp` and show how to [obtain the base path from app settings or other configuration providers](xref:blazor/host-and-deploy/app-base-path#obtain-the-app-base-path-from-configuration). * Follow the sub-application configuration guidance in . The sub-app's folder path under the root site becomes the virtual path of the sub-app. For an app base path of `/CoolApp`, the Blazor app is placed in a folder named `CoolApp` under the root site and the sub-app takes on a virtual path of `/CoolApp`. diff --git a/aspnetcore/blazor/host-and-deploy/webassembly/azure-static-web-apps.md b/aspnetcore/blazor/host-and-deploy/webassembly/azure-static-web-apps.md index 35929ea56127..1d79f9294dd8 100644 --- a/aspnetcore/blazor/host-and-deploy/webassembly/azure-static-web-apps.md +++ b/aspnetcore/blazor/host-and-deploy/webassembly/azure-static-web-apps.md @@ -1,18 +1,18 @@ --- -title: Host and deploy ASP.NET Core Blazor WebAssembly with Azure Static Web Apps +title: Host and deploy ASP.NET Core standalone Blazor WebAssembly with Azure Static Web Apps author: guardrex -description: Learn how to host and deploy Blazor WebAssembly with Microsoft Azure Static Web Apps. +description: Learn how to host and deploy standalone Blazor WebAssembly with Microsoft Azure Static Web Apps. monikerRange: '>= aspnetcore-3.1' ms.author: riande ms.custom: mvc ms.date: 03/31/2025 uid: blazor/host-and-deploy/webassembly/azure-static-web-apps --- -# Host and deploy ASP.NET Core Blazor WebAssembly with Azure Static Web Apps +# Host and deploy ASP.NET Core standalone Blazor WebAssembly with Azure Static Web Apps [!INCLUDE[](~/includes/not-latest-version.md)] -This article explains how to host and deploy Blazor WebAssembly with [Microsoft Azure Static Web Apps](https://azure.microsoft.com/products/app-service/static). +This article explains how to host and deploy standalone Blazor WebAssembly with [Microsoft Azure Static Web Apps](https://azure.microsoft.com/products/app-service/static). ## Deploy from Visual Studio diff --git a/aspnetcore/blazor/host-and-deploy/webassembly/azure-storage.md b/aspnetcore/blazor/host-and-deploy/webassembly/azure-storage.md index 65b9d5c563a9..b56ca16951d9 100644 --- a/aspnetcore/blazor/host-and-deploy/webassembly/azure-storage.md +++ b/aspnetcore/blazor/host-and-deploy/webassembly/azure-storage.md @@ -1,18 +1,18 @@ --- -title: Host and deploy ASP.NET Core Blazor WebAssembly with Azure Storage +title: Host and deploy ASP.NET Core standalone Blazor WebAssembly with Azure Storage author: guardrex -description: Learn how to host and deploy Blazor WebAssembly using Microsoft Azure Storage. +description: Learn how to host and deploy standalone Blazor WebAssembly using Microsoft Azure Storage. monikerRange: '>= aspnetcore-3.1' ms.author: riande ms.custom: mvc ms.date: 03/31/2025 uid: blazor/host-and-deploy/webassembly/azure-storage --- -# Host and deploy ASP.NET Core Blazor WebAssembly with Azure Storage +# Host and deploy ASP.NET Core standalone Blazor WebAssembly with Azure Storage [!INCLUDE[](~/includes/not-latest-version.md)] -This article explains how to host and deploy Blazor WebAssembly using [Microsoft Azure Storage](/azure/storage/common/storage-introduction). +This article explains how to host and deploy standalone Blazor WebAssembly using [Microsoft Azure Storage](/azure/storage/common/storage-introduction). Azure Storage static file hosting allows serverless Blazor app hosting. Custom domain names, the Azure Content Delivery Network (CDN), and HTTPS are supported. diff --git a/aspnetcore/blazor/host-and-deploy/webassembly/github-pages.md b/aspnetcore/blazor/host-and-deploy/webassembly/github-pages.md index 02b6e224daf6..184a311235c6 100644 --- a/aspnetcore/blazor/host-and-deploy/webassembly/github-pages.md +++ b/aspnetcore/blazor/host-and-deploy/webassembly/github-pages.md @@ -1,18 +1,18 @@ --- -title: Host and deploy ASP.NET Core Blazor WebAssembly with GitHub Pages +title: Host and deploy ASP.NET Core standalone Blazor WebAssembly with GitHub Pages author: guardrex -description: Learn how to host and deploy Blazor WebAssembly using GitHub Pages. +description: Learn how to host and deploy standalone Blazor WebAssembly using GitHub Pages. monikerRange: '>= aspnetcore-3.1' ms.author: riande ms.custom: mvc ms.date: 03/31/2025 uid: blazor/host-and-deploy/webassembly/github-pages --- -# Host and deploy ASP.NET Core Blazor WebAssembly with GitHub Pages +# Host and deploy ASP.NET Core standalone Blazor WebAssembly with GitHub Pages [!INCLUDE[](~/includes/not-latest-version.md)] -This article explains how to host and deploy Blazor WebAssembly using [GitHub Pages](https://pages.github.com/). +This article explains how to host and deploy standalone Blazor WebAssembly using [GitHub Pages](https://pages.github.com/). The following guidance for GitHub Pages deployments of Blazor WebAssembly apps demonstrates concepts with a live tool deployed to GitHub Pages. The tool is used by the ASP.NET Core documentation authors to create cross-reference (XREF) links to API documentation for article markdown: