Skip to content
22 changes: 21 additions & 1 deletion .openpublishing.redirection.json
Original file line number Diff line number Diff line change
Expand Up @@ -1649,10 +1649,30 @@
"redirect_url": "/aspnet/core/fundamentals/error-handling-api",
"redirect_document_id": false
},
{
{
"source_path": "aspnetcore/fundamentals/map-static-files.md",
"redirect_url": "/aspnet/core/fundamentals/static-files",
"redirect_document_id": false
},
{
"source_path": "aspnetcore/migration/60-70.md",
"redirect_url": "/aspnet/core/migration/60-to-70",
"redirect_document_id": false
},
{
"source_path": "aspnetcore/migration/70-80.md",
"redirect_url": "/aspnet/core/migration/70-to-80",
"redirect_document_id": false
},
{
"source_path": "aspnetcore/migration/80-90.md",
"redirect_url": "/aspnet/core/migration/80-to-90",
"redirect_document_id": false
},
{
"source_path": "aspnetcore/migration/20_21.md",
"redirect_url": "/aspnet/core/migration/20-to-21",
"redirect_document_id": false
}
]
}
19 changes: 18 additions & 1 deletion aspnetcore/blazor/call-web-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,24 @@ The solution includes a demonstration of obtaining weather data securely via an
## Disposal of `HttpRequestMessage`, `HttpResponseMessage`, and `HttpClient`
An <xref:System.Net.Http.HttpRequestMessage> without a body doesn't require explicit disposal with a [`using` declaration (C# 8 or later)](/dotnet/csharp/language-reference/proposals/csharp-8.0/using) or a [`using` block (all C# releases)](/dotnet/csharp/language-reference/keywords/using), but we recommend disposing with every use for the following reasons:
An <xref:System.Net.Http.HttpRequestMessage> without a body doesn't require explicit disposal. However, you can dispose of it with either of the following patterns:
* `using` declaration (C# 8 or later):
```csharp
using var request = new HttpRequestMessage(...);
```
* [`using` block (all C# releases)](/dotnet/csharp/language-reference/keywords/using):
```csharp
using (var request = new HttpRequestMessage(...))
{
...
}
```
We recommend disposing of every <xref:System.Net.Http.HttpRequestMessage> with every use for the following reasons:
* To gain a performance improvement by avoiding finalizers.
* It hardens the code for the future in case a request body is ever added to an <xref:System.Net.Http.HttpRequestMessage> that didn't initially have one.
Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/components/quickgrid.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Set the `QuickGrid` component's <xref:Microsoft.AspNetCore.Components.QuickGrid.
<QuickGrid Items="..." Pagination="pagination">
```

<!-- UPDATE 10.0 Tracked by https://github.com/dotnet/aspnetcore/issues/57289
<!-- UPDATE 11.0 Tracked by https://github.com/dotnet/aspnetcore/issues/57289
for multiple paginator components problem. -->

To provide a UI for pagination, add a [`Paginator` component](xref:Microsoft.AspNetCore.Components.QuickGrid.Paginator) above or below the `QuickGrid` component. Set the <xref:Microsoft.AspNetCore.Components.QuickGrid.Paginator.State%2A?displayProperty=nameWithType> to `pagination`:
Expand Down
5 changes: 1 addition & 4 deletions aspnetcore/blazor/components/rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,4 @@ The state manager approach is similar to the earlier case with <xref:System.Time

## WebAssembly loading progress indicator for Blazor Web Apps

<!-- UPDATE 10.0 Will be removed for a new feature in this area.
Tracked by: https://github.com/dotnet/aspnetcore/issues/49056 -->

A loading progress indicator isn't present in an app created from the Blazor Web App project template. A new loading progress indicator feature is planned for a future release of .NET. In the meantime, an app can adopt custom code to create a loading progress indicator. For more information, see <xref:blazor/fundamentals/startup#client-side-loading-indicators>.
An app can adopt custom code to create a loading progress indicator. For more information, see <xref:blazor/fundamentals/startup#client-side-loading-indicators>.
21 changes: 5 additions & 16 deletions aspnetcore/blazor/file-uploads.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,6 @@ await blobContainerClient.UploadBlobAsync(

A component that receives an image file can call the <xref:Microsoft.AspNetCore.Components.Forms.BrowserFileExtensions.RequestImageFileAsync%2A?displayProperty=nameWithType> convenience method on the file to resize the image data within the browser's JavaScript runtime before the image is streamed into the app. Use cases for calling <xref:Microsoft.AspNetCore.Components.Forms.BrowserFileExtensions.RequestImageFileAsync%2A> are most appropriate for Blazor WebAssembly apps.

:::moniker range="< aspnetcore-9.0"

<!-- UPDATE 10.0 Remove this section. Leave the coverage in the
Troubleshoot section. -->

## Autofac Inversion of Control (IoC) container users

If you're using the [Autofac Inversion of Control (IoC) container](https://autofac.org/) instead of the built-in ASP.NET Core dependency injection container, set <xref:Microsoft.AspNetCore.SignalR.HubOptions.DisableImplicitFromServicesParameters%2A> to `true` in the [server-side circuit handler hub options](xref:blazor/fundamentals/signalr#server-side-circuit-handler-options). For more information, see [FileUpload: Did not receive any data in the allotted time (`dotnet/aspnetcore` #38842)](https://github.com/dotnet/aspnetcore/issues/38842#issuecomment-1342540950).

:::moniker-end

## File size read and upload limits

:::moniker range=">= aspnetcore-9.0"
Expand Down Expand Up @@ -293,7 +282,7 @@ public class UploadResult

A security best practice for production apps is to avoid sending error messages to clients that might reveal sensitive information about an app, server, or network. Providing detailed error messages can aid a malicious user in devising attacks on an app, server, or network. The example code in this section only sends back an error code number (`int`) for display by the component client-side if a server-side error occurs. If a user requires assistance with a file upload, they provide the error code to support personnel for support ticket resolution without ever knowing the exact cause of the error.

<!-- UPDATE 10.0 HOLD moniker range="< aspnetcore-10.0"
<!-- UPDATE 11.0 HOLD moniker range="< aspnetcore-11.0"
https://github.com/dotnet/aspnetcore/issues/47301
No doc issue yet, but tracked by ...
https://github.com/dotnet/AspNetCore.Docs/issues/34437 -->
Expand All @@ -302,9 +291,9 @@ The following `LazyBrowserFileStream` class defines a custom stream type that la

`LazyBrowserFileStream.cs`:

<!-- UPDATE 10.0 HOLD moniker-end -->
<!-- UPDATE 11.0 HOLD moniker-end -->

<!-- UPDATE 10.0 HOLD for next line: < aspnetcore-10.0 -->
<!-- UPDATE 11.0 HOLD for next line: < aspnetcore-11.0 -->

:::moniker range=">= aspnetcore-8.0"

Expand Down Expand Up @@ -369,7 +358,7 @@ The following `FileUpload2` component:

:::moniker-end

<!-- UPDATE 10.0 HOLD for the next line: < aspnetcore-10.0 -->
<!-- UPDATE 11.0 HOLD for the next line: < aspnetcore-11.0 -->

:::moniker range=">= aspnetcore-8.0"

Expand Down Expand Up @@ -1297,7 +1286,7 @@ Possible causes:

* Not reading the stream to completion. This isn't a framework issue. Trap the exception and investigate it further in your local environment/network.

<!-- UPDATE 10.0 - Version the following out at 10.0 when the
<!-- UPDATE 11.0 - Version the following out at 11.0 when the
the `LazyBrowserFileStream` class is dropped
because the underlying problem is fixed. -->

Expand Down
4 changes: 2 additions & 2 deletions aspnetcore/blazor/forms/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,9 @@ jQuery validation isn't supported in Razor components. We recommend any of the f
* Use native HTML validation attributes (see [Client-side form validation](https://developer.mozilla.org/docs/Learn/Forms/Form_validation)).
* Adopt a third-party validation JavaScript library.

<!-- UPDATE 10.0 - Remove if the feature is realized. -->
<!-- UPDATE 11.0 - Remove if the feature is realized or dropped. -->

For statically-rendered forms on the server, a new mechanism for client-side validation is under consideration for .NET 10 in late 2025. For more information, see [Create server rendered forms with client validation using Blazor without a circuit (`dotnet/aspnetcore` #51040)](https://github.com/dotnet/aspnetcore/issues/51040).
For statically-rendered forms on the server, a new mechanism for client-side validation is under consideration. For more information, see [Create server rendered forms with client validation using Blazor without a circuit (`dotnet/aspnetcore` #51040)](https://github.com/dotnet/aspnetcore/issues/51040).

## Additional resources

Expand Down
2 changes: 0 additions & 2 deletions aspnetcore/blazor/fundamentals/dependency-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,6 @@ public IMyService MyService { get; set; }

## Utility base component classes to manage a DI scope

<!-- UPDATE 10.0 - PU design is under consideration for .NET 10. -->

In non-Blazor ASP.NET Core apps, scoped and transient services are typically scoped to the current request. After the request completes, scoped and transient services are disposed by the DI system.

In interactive server-side Blazor apps, the DI scope lasts for the duration of the circuit (the SignalR connection between the client and server), which can result in scoped and disposable transient services living much longer than the lifetime of a single component. Therefore, don't directly inject a scoped service into a component if you intend the service lifetime to match the lifetime of the component. Transient services injected into a component that don't implement <xref:System.IDisposable> are garbage collected when the component is disposed. However, injected transient services *that implement <xref:System.IDisposable>* are maintained by the DI container for the lifetime of the circuit, which prevents service garbage collection when the component is disposed and results in a memory leak. An alternative approach for scoped services based on the <xref:Microsoft.AspNetCore.Components.OwningComponentBase> type is described later in this section, and disposable transient services shouldn't be used at all. For more information, see [Design for solving transient disposables on Blazor Server (`dotnet/aspnetcore` #26676)](https://github.com/dotnet/aspnetcore/issues/26676).
Expand Down
4 changes: 0 additions & 4 deletions aspnetcore/blazor/fundamentals/environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ uid: blazor/fundamentals/environments
This article explains how to configure and read the [environment](xref:fundamentals/environments) in a Blazor app.

When running an app locally, the environment defaults to `Development`. When the app is published, the environment defaults to `Production`.

<!-- UPDATE 10.0 The underlying problem with app settings filename
case sensitivity is tracked for 10.0 by ...
https://github.com/dotnet/aspnetcore/issues/25152 -->

We recommend the following conventions:

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/fundamentals/signalr.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ app.MapBlazorHub(options =>
});
```

<!-- UPDATE 10.0 - The following is scheduled for a fix in .NET 10.
<!-- UPDATE 11.0 - The following is scheduled for a fix in .NET 11.
Tracked by: https://github.com/dotnet/aspnetcore/issues/63520 -->

Configuring the hub used by <xref:Microsoft.AspNetCore.Builder.ServerRazorComponentsEndpointConventionBuilderExtensions.AddInteractiveServerRenderMode%2A> with <xref:Microsoft.AspNetCore.Builder.ComponentEndpointRouteBuilderExtensions.MapBlazorHub%2A> fails with an <xref:System.Reflection.AmbiguousMatchException>:
Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/host-and-deploy/configure-trimmer.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Blazor WebAssembly performs [Intermediate Language (IL)](/dotnet/standard/glossa

## Default trimmer granularity

<!-- UPDATE 10.0 - HOLD until https://github.com/dotnet/aspnetcore/issues/49409
<!-- UPDATE 11.0 - HOLD until https://github.com/dotnet/aspnetcore/issues/49409
is addressed.

The default trimmer granularity for Blazor apps is `partial`. To trim all assemblies, change the granularity to `full` in the app's project file:
Expand Down
46 changes: 37 additions & 9 deletions aspnetcore/blazor/project-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -540,19 +540,27 @@ The project structure of the client-side app in a hosted Blazor Webassembly solu

The Blazor script is served as a static web asset with automatic compression and fingerprinting. For more information, see <xref:blazor/fundamentals/static-files>.

:::moniker-end
In a Blazor Web App, the Blazor script is located in the `Components/App.razor` file:

:::moniker range="< aspnetcore-10.0"
```razor
<script src="@Assets["_framework/blazor.web.js"]"></script>
```

The Blazor script is served from an embedded resource in the ASP.NET Core shared framework.
In a Blazor Server app, the Blazor script is located in the `Pages/_Host.cshtml` file:

```html
<script src="_framework/blazor.server.js"></script>
```

:::moniker-end

:::moniker range=">= aspnetcore-8.0"
:::moniker range=">= aspnetcore-8.0 < aspnetcore-10.0"

The Blazor script is served from an embedded resource in the ASP.NET Core shared framework.

In a Blazor Web App, the Blazor script is located in the `Components/App.razor` file:

```html
```razor
<script src="_framework/blazor.web.js"></script>
```

Expand All @@ -566,6 +574,8 @@ In a Blazor Server app, the Blazor script is located in the `Pages/_Host.cshtml`

:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"

The Blazor script is served from an embedded resource in the ASP.NET Core shared framework.

In a Blazor Server app, the Blazor script is located in the `Pages/_Host.cshtml` file:

```html
Expand All @@ -576,6 +586,8 @@ In a Blazor Server app, the Blazor script is located in the `Pages/_Host.cshtml`

:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"

The Blazor script is served from an embedded resource in the ASP.NET Core shared framework.

In a Blazor Server app, the Blazor script is located in the `Pages/_Layout.cshtml` file:

```html
Expand All @@ -586,6 +598,8 @@ In a Blazor Server app, the Blazor script is located in the `Pages/_Layout.cshtm

:::moniker range="< aspnetcore-6.0"

The Blazor script is served from an embedded resource in the ASP.NET Core shared framework.

In a Blazor Server app, the Blazor script is located in the `Pages/_Host.cshtml` file:

```html
Expand All @@ -594,18 +608,32 @@ In a Blazor Server app, the Blazor script is located in the `Pages/_Host.cshtml`

:::moniker-end

For a Blazor Web App or a Blazor Server app, the project must contain at least one Razor component file (`.razor`) in order to automatically include the Blazor script when the app is published. If the project doesn't contain at least one Razor component, set the `RequiresAspNetWebAssets` MSBuild property to `true` in the app's project file to include the Blazor script:

```xml
<RequiresAspNetWebAssets>true</RequiresAspNetWebAssets>
```

In a Blazor WebAssembly app, the Blazor script content is located in the `wwwroot/index.html` file:

:::moniker range=">= aspnetcore-10.0"

```html
<script src="_framework/blazor.webassembly.js"></script>
<script src="_framework/blazor.webassembly#[.{fingerprint}].js"></script>
```

For a Blazor Web App or a Blazor Server app, the project must contain at least one Razor component file (`.razor`) in order to automatically include the Blazor script when the app is published. If the project doesn't contain at least one Razor component, set the `RequiresAspNetWebAssets` MSBuild property `true` in the app's project file to include the Blazor script:
When the app is published, the `{fingerprint}` placeholder is automatically replaced with a unique hash for cache busting.

```xml
<RequiresAspNetWebAssets>true</RequiresAspNetWebAssets>
:::moniker-end

:::moniker range="< aspnetcore-10.0"

```html
<script src="_framework/blazor.webassembly.js"></script>
```

:::moniker-end

## Location of `<head>` and `<body>` content

:::moniker range=">= aspnetcore-8.0"
Expand Down
5 changes: 0 additions & 5 deletions aspnetcore/blazor/webassembly-build-tools-and-aot.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,10 @@ To target a prior .NET release with a given .NET SDK, install the `wasm-tools-ne

The following list shows which workload to install for each .NET SDK, depending on the apps that you plan to target. Although multiple rows may contain the same workload name, the workloads always differ slightly for each particular .NET SDK.

<!-- UPDATE 10.0 - Surface new content

* Using the .NET 10 SDK
* Targeting .NET 10 requires `wasm-tools`.
* Targeting .NET 9 requires `wasm-tools-net9`.
* Targeting .NET 8 requires `wasm-tools-net8`.

-->

* Using the .NET 9 SDK
* Targeting .NET 9 requires `wasm-tools`.
* Targeting .NET 8 requires `wasm-tools-net8`.
Expand Down
21 changes: 16 additions & 5 deletions aspnetcore/diagnostics/asp0026.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
---
title: "ASP0026: Analyzer to warn when [Authorize] is overridden by [AllowAnonymous] from 'farther away'"
ms.date: 03/27/2025
description: "Learn about analysis rule ASP0026: [Authorize] is overridden by [AllowAnonymous] from 'farther away'"
ai-usage: ai-assisted
author: tdykstra
description: "Learn about analysis rule ASP0026: [Authorize] is overridden by [AllowAnonymous] from 'farther away'"
monikerRange: '>= aspnetcore-9.0'
ms.author: tdykstra
ms.date: 11/06/2025
uid: diagnostics/asp0026
---
# ASP0026: `[Authorize]` is overridden by `[AllowAnonymous]` from "farther away"
Expand All @@ -19,6 +20,9 @@ uid: diagnostics/asp0026

It seems intuitive that an `[Authorize]` attribute placed "closer" to an MVC action than an `[AllowAnonymous]` attribute would override the `[AllowAnonymous]` attribute and force authorization. However, this is not necessarily the case. What does matter is the relative order of the attributes.

> [!NOTE]
> The `[AllowAnonymous]` attribute doesn't disable authentication entirely. When credentials are sent to an endpoint with `[AllowAnonymous]`, the endpoint still authenticates those credentials and establishes the user's identity. The `[AllowAnonymous]` attribute only means that authentication is **not required**—the endpoint will run as anonymous only when no credentials are provided. This behavior can be useful for endpoints that need to work for both authenticated and anonymous users.

The following code shows examples where a closer `[Authorize]` attribute gets overridden by an `[AllowAnonymous]` attribute that is farther away.

```csharp
Expand Down Expand Up @@ -58,7 +62,12 @@ public class MyControllerMultiple : ControllerBase

## Rule description

Warning that an `[Authorize]` attribute is overridden by an `[AllowAnonymous]` attribute from "farther away."
This warning indicates that an `[Authorize]` attribute is overridden by an `[AllowAnonymous]` attribute from "farther away." When `[AllowAnonymous]` takes precedence, the endpoint doesn't require authentication but still accepts and processes credentials if they're provided. This means:

- If a request includes authentication credentials, the endpoint authenticates the user and makes their identity available.
- If a request doesn't include credentials, the endpoint allows anonymous access.

This behavior might unintentionally expose endpoints that were meant to require authentication.

## How to fix violations

Expand All @@ -70,8 +79,10 @@ public class MyController
{
// This produces no warning because the second, "closer" [AllowAnonymous]
// clarifies that [Authorize] is intentionally overridden.
// Specifying AuthenticationSchemes can still be useful
// for endpoints that allow but don't require authenticated users.
// Specifying AuthenticationSchemes can be useful for endpoints that
// allow but don't require authenticated users. When credentials are sent,
// they will be authenticated; when no credentials are sent, the endpoint
// allows anonymous access.
[Authorize(AuthenticationSchemes = "Cookies")]
[AllowAnonymous]
public IActionResult Privacy() => null;
Expand Down
Loading
Loading