Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions aspnetcore/breaking-changes/10/apidescription-client-deprecated.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: "Breaking change - Microsoft.Extensions.ApiDescription.Client package deprecated"
description: "Learn about the breaking change in ASP.NET Core 10 where the Microsoft.Extensions.ApiDescription.Client package has been deprecated."
ms.date: 08/07/2025
ai-usage: ai-assisted
ms.custom: https://github.com/aspnet/Announcements/issues/518
---

# Microsoft.Extensions.ApiDescription.Client package deprecated

The Microsoft.Extensions.ApiDescription.Client NuGet package has been deprecated. The package supplied MSBuild targets and CLI support that generated OpenAPI-based client code during the build. Projects that reference the package now receive a warning during build.

## Version introduced

.NET 10 Preview 7

## Previous behavior

Projects could add `<PackageReference Include="Microsoft.Extensions.ApiDescription.Client" ... />` and `<OpenApiReference>` items (or run `dotnet openapi`) to generate strongly typed clients at build time.

```xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.ApiDescription.Client" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<OpenApiReference Include="swagger.json" />
</ItemGroup>
</Project>
```

## New behavior

The package is now deprecated and projects that reference it receive build warnings. The MSBuild targets and CLI commands are no longer supported.

## Type of breaking change

This change can affect [source compatibility](/dotnet/core/compatibility/categories#source-compatibility).

## Reason for change

- The package has seen minimal updates and maintenance since its introduction.
- Its abstractions were tightly coupled to certain generators and did not scale well to others. Each generator now ships its own CLI/configuration experience, making the MSBuild middle-layer redundant.
- Removing the package reduces maintenance burden and clarifies the recommended workflow for client generation.

## Recommended action

- Remove any `<PackageReference Include="Microsoft.Extensions.ApiDescription.Client" … />` from your project.
- Replace `<OpenApiReference>` items or `dotnet openapi` commands with generator-specific tooling:
- NSwag – Use `npx nswag` or `dotnet tool run nswag` with an `.nswag` config file.
- Kiota – Install with `dotnet tool install -g Microsoft.OpenApi.Kiota` and run `kiota generate`.
- OpenAPI generator – Invoke `openapi-generator-cli` via JAR or Docker.
- Commit the generated client code or run generation in a custom pre-build step that doesn't rely on the removed package.

## Affected APIs

- MSBuild item `OpenApiReference` (all instances).
- MSBuild property `OpenApiProjectReference`.
- CLI command [`dotnet openapi`](/aspnet/core/fundamentals/openapi/openapi-tools).
110 changes: 110 additions & 0 deletions aspnetcore/breaking-changes/10/cookie-authentication-api-endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: "Cookie login redirects are disabled for known API endpoints"
description: "Learn about the breaking change in ASP.NET Core 10 where cookie authentication no longer redirects to login or access denied URIs for known API endpoints."
ms.date: 08/08/2025
ai-usage: ai-assisted
ms.custom: https://github.com/aspnet/Announcements/issues/525
---

# Cookie login redirects are disabled for known API endpoints

By default, unauthenticated and unauthorized requests made to known API endpoints protected by cookie authentication now result in 401 and 403 responses rather than redirecting to a login or access-denied URI.

Known API [endpoints](/aspnet/core/fundamentals/routing) are identified using the new `IApiEndpointMetadata` <!--xref:Microsoft.AspNetCore.Http.Metadata.IApiEndpointMetadata--> interface, and metadata implementing the new interface has been added automatically to the following:

- [`[ApiController]`](xref:Microsoft.AspNetCore.Mvc.ApiControllerAttribute) endpoints.
- Minimal API endpoints that read JSON request bodies or write JSON responses.
- Endpoints using <xref:Microsoft.AspNetCore.Http.TypedResults> return types.
- SignalR endpoints.

## Version introduced

.NET 10 Preview 7

## Previous behavior

Previously, the cookie authentication handler redirected unauthenticated and unauthorized requests to a login or access-denied URI by default for all requests other than [XMLHttpRequests (XHRs)](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest).

## New behavior

Starting in .NET 10, unauthenticated and unauthorized requests made to known API endpoints result in 401 and 403 responses rather than redirecting to a login or access-denied URI. XHRs continue to result in 401 and 403 responses regardless of the target endpoint.

## Type of breaking change

This change is a [behavioral change](/dotnet/core/compatibility/categories#behavioral-change).

## Reason for change

This change was highly requested. Redirecting unauthenticated requests to a login page doesn't usually make sense for API endpoints, which typically rely on 401 and 403 status codes rather than HTML redirects to communicate auth failures.

## Recommended action

If you want to always redirect to the login and access-denied URIs for unauthenticated or unauthorized requests regardless of the target endpoint or whether the source of the request is an XHR, you can override <xref:Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents.RedirectToLogin*> and <xref:Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents.RedirectToAccessDenied*> as follows:

```csharp
builder.Services.AddAuthentication()
.AddCookie(options =>
{
options.Events.OnRedirectToLogin = context =>
{
context.Response.Redirect(context.RedirectUri);
return Task.CompletedTask;
};

options.Events.OnRedirectToAccessDenied = context =>
{
context.Response.Redirect(context.RedirectUri);
return Task.CompletedTask;
};
});
```

If you want to revert to the exact previous behavior that avoids redirecting for only XHRs, you can override the events with this slightly more complicated logic:

```csharp
builder.Services.AddAuthentication()
.AddCookie(options =>
{
bool IsXhr(HttpRequest request)
{
return string.Equals(request.Query[HeaderNames.XRequestedWith], "XMLHttpRequest", StringComparison.Ordinal) ||
string.Equals(request.Headers.XRequestedWith, "XMLHttpRequest", StringComparison.Ordinal);
}

options.Events.OnRedirectToLogin = context =>
{
if (IsXhr(context.Request))
{
context.Response.Headers.Location = context.RedirectUri;
context.Response.StatusCode = 401;
}
else
{
context.Response.Redirect(context.RedirectUri);
}

return Task.CompletedTask;
};

options.Events.OnRedirectToAccessDenied = context =>
{
if (IsXhr(context.Request))
{
context.Response.Headers.Location = context.RedirectUri;
context.Response.StatusCode = 403;
}
else
{
context.Response.Redirect(context.RedirectUri);
}

return Task.CompletedTask;
};
});
```

## Affected APIs

- `Microsoft.AspNetCore.Http.Metadata.IApiEndpointMetadata` <!--xref:Microsoft.AspNetCore.Http.Metadata.IApiEndpointMetadata?displayProperty=fullName-->
- <xref:Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents.RedirectToLogin*?displayProperty=fullName>
- <xref:Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents.RedirectToAccessDenied*?displayProperty=fullName>
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: "Breaking change: Exception diagnostics are suppressed when IExceptionHandler.TryHandleAsync returns true"
description: Learn about the breaking change in ASP.NET Core 10 where exception diagnostics are no longer recorded when IExceptionHandler.TryHandleAsync returns true.
ms.date: 08/08/2025
ms.custom: https://github.com/aspnet/Announcements/issues/524
---

# Exception diagnostics are suppressed when IExceptionHandler.TryHandleAsync returns true

The ASP.NET Core exception handler middleware no longer records diagnostics for exceptions handled by <xref:Microsoft.AspNetCore.Diagnostics.IExceptionHandler> by default.

## Version introduced

.NET 10 Preview 7

## Previous behavior

Previously, the exception handler middleware recorded diagnostics about exceptions handled by <xref:Microsoft.AspNetCore.Diagnostics.IExceptionHandler>.

The exception diagnostics are:

- Logging `UnhandledException` to <xref:Microsoft.Extensions.Logging.ILogger>.
- Writing the `Microsoft.AspNetCore.Diagnostics.HandledException` event to <xref:Microsoft.Extensions.Logging.EventSource>.
- Adding the `error.type` tag to the `http.server.request.duration` metric.

## New behavior

Starting in .NET 10, if <xref:Microsoft.AspNetCore.Diagnostics.IExceptionHandler.TryHandleAsync%2A?displayProperty=nameWithType> returns `true`, then exception diagnostics are no longer recorded by default.

## Type of breaking change

This change is a [behavioral change](/dotnet/core/compatibility/categories#behavioral-change).

## Reason for change

ASP.NET Core users have given feedback that the previous behavior was undesirable. Their <xref:Microsoft.AspNetCore.Diagnostics.IExceptionHandler> implementation reported that the exception was handled, but the error handling middleware still recorded the error in the app's telemetry.

ASP.NET Core now follows the behavior expected by users by suppressing diagnostics when <xref:Microsoft.AspNetCore.Diagnostics.IExceptionHandler> handles the exception. Configuration options are also available to customize exception diagnostics behavior if needed.

## Recommended action

If you want handled exceptions to continue to record telemetry, you can use the new `ExceptionHandlerOptions.SuppressDiagnosticsCallback` option:

```csharp
app.UseExceptionHandler(new ExceptionHandlerOptions
{
SuppressDiagnosticsCallback = context => false;
});
```

The `context` passed to the callback includes information about the exception, the request, and whether the exception was handled. The callback returns `false` to indicate that diagnostics shouldn't be suppressed, thus restoring the previous behavior.

## Affected APIs

- <xref:Microsoft.AspNetCore.Builder.ExceptionHandlerExtensions.UseExceptionHandler%2A?displayProperty=fullName>
- <xref:Microsoft.AspNetCore.Diagnostics.IExceptionHandler?displayProperty=fullName>
104 changes: 104 additions & 0 deletions aspnetcore/breaking-changes/10/iactioncontextaccessor-obsolete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: "IActionContextAccessor and ActionContextAccessor are obsolete"
description: "Learn about the breaking change in ASP.NET Core 10 where IActionContextAccessor and ActionContextAccessor are marked as obsolete."
ms.date: 08/07/2025
ai-usage: ai-assisted
ms.custom: https://github.com/aspnet/Announcements/issues/520
---

# IActionContextAccessor and ActionContextAccessor are obsolete

<xref:Microsoft.AspNetCore.Mvc.Infrastructure.IActionContextAccessor> and <xref:Microsoft.AspNetCore.Mvc.Infrastructure.ActionContextAccessor> have been marked as obsolete with diagnostic ID `ASPDEPR006`. With the introduction of endpoint routing, `IActionContextAccessor` is no longer necessary as developers can access action descriptor and metadata information directly through `HttpContext.GetEndpoint()`.

## Version introduced

.NET 10 Preview 7

## Previous behavior

Previously, you could use `IActionContextAccessor` to access the current <xref:Microsoft.AspNetCore.Mvc.ActionContext>:

```csharp
public class MyService
{
private readonly IActionContextAccessor _actionContextAccessor;

public MyService(IActionContextAccessor actionContextAccessor)
{
_actionContextAccessor = actionContextAccessor;
}

public void DoSomething()
{
var actionContext = _actionContextAccessor.ActionContext;
var actionDescriptor = actionContext?.ActionDescriptor;
// Use action descriptor metadata.
}
}
```

## New behavior

Starting in .NET 10, using `IActionContextAccessor` and `ActionContextAccessor` produces a compiler warning with diagnostic ID `ASPDEPR006`:

> warning ASPDEPR006: ActionContextAccessor is obsolete and will be removed in a future version. For more information, visit <https://aka.ms/aspnet/deprecate/006>.

## Type of breaking change

This change can affect [source compatibility](/dotnet/core/compatibility/categories#source-compatibility).

## Reason for change

With the introduction of endpoint routing in ASP.NET Core, `IActionContextAccessor` is no longer necessary. The endpoint routing infrastructure provides a cleaner, more direct way to access endpoint metadata through `HttpContext.GetEndpoint()`, aligning with ASP.NET Core's architectural evolution toward endpoint routing.

## Recommended action

Migrate from `IActionContextAccessor` to <xref:Microsoft.AspNetCore.Http.IHttpContextAccessor> and use `HttpContext.GetEndpoint()`:

Before:

```csharp
public class MyService
{
private readonly IActionContextAccessor _actionContextAccessor;

public MyService(IActionContextAccessor actionContextAccessor)
{
_actionContextAccessor = actionContextAccessor;
}

public void DoSomething()
{
var actionContext = _actionContextAccessor.ActionContext;
var actionDescriptor = actionContext?.ActionDescriptor;
// Use action descriptor metadata
}
}
```

After:

```csharp
public class MyService
{
private readonly IHttpContextAccessor _httpContextAccessor;

public MyService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}

public void DoSomething()
{
var httpContext = _httpContextAccessor.HttpContext;
var endpoint = httpContext?.GetEndpoint();
var actionDescriptor = endpoint?.Metadata.GetMetadata<ActionDescriptor>();
// Use action descriptor metadata.
}
}
```

## Affected APIs

- <xref:Microsoft.AspNetCore.Mvc.Infrastructure.IActionContextAccessor?displayProperty=fullName>
- <xref:Microsoft.AspNetCore.Mvc.Infrastructure.ActionContextAccessor?displayProperty=fullName>
50 changes: 50 additions & 0 deletions aspnetcore/breaking-changes/10/ipnetwork-knownnetworks-obsolete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
title: "Breaking change: IPNetwork and ForwardedHeadersOptions.KnownNetworks are obsolete"
description: Learn about the breaking change in ASP.NET Core 10.0 where IPNetwork and ForwardedHeadersOptions.KnownNetworks have been obsoleted in favor of System.Net.IPNetwork and KnownIPNetworks.
ms.date: 08/08/2025
ai-usage: ai-assisted
ms.custom: https://github.com/aspnet/Announcements/issues/523
---
# IPNetwork and ForwardedHeadersOptions.KnownNetworks are obsolete

<xref:Microsoft.AspNetCore.HttpOverrides.IPNetwork?displayProperty=fullName> and <xref:Microsoft.AspNetCore.Builder.ForwardedHeadersOptions.KnownNetworks> have been marked as obsolete in favor of using <xref:System.Net.IPNetwork?displayProperty=fullName> and `KnownIPNetworks`.

## Version introduced

.NET 10 Preview 7

## Previous behavior

Previously, you could use <xref:Microsoft.AspNetCore.HttpOverrides.IPNetwork?displayProperty=fullName> and <xref:Microsoft.AspNetCore.Builder.ForwardedHeadersOptions.KnownNetworks> to configure known networks for the forwarded headers middleware:

```csharp
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
KnownNetworks.Add(new(IPAddress.Loopback, 8))
});
```

## New behavior

Starting in .NET 10, if you use [the obsolete APIs](#affected-apis) in your code, you'll get warning `ASPDEPR005` at compile time:

> warning ASPDEPR005: Please use KnownIPNetworks instead. For more information, visit <https://aka.ms/aspnet/deprecate/005>.

Use the <xref:System.Net.IPNetwork?displayProperty=fullName> type and `KnownIPNetworks` property instead.

## Type of breaking change

This change can affect [source compatibility](/dotnet/core/compatibility/categories#source-compatibility).

## Reason for change

<xref:System.Net.IPNetwork?displayProperty=fullName> has replaced the <xref:Microsoft.AspNetCore.HttpOverrides.IPNetwork?displayProperty=fullName> type that was implemented for <xref:Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware>.

## Recommended action

Change to using <xref:System.Net.IPNetwork?displayProperty=fullName> and `KnownIPNetworks`.

## Affected APIs

- <xref:Microsoft.AspNetCore.HttpOverrides.IPNetwork?displayProperty=fullName>
- <xref:Microsoft.AspNetCore.Builder.ForwardedHeadersOptions.KnownNetworks?displayProperty=fullName>
Loading
Loading