ASP.NET Core breaking changes

ASP.NET Core provides the web app development features used by .NET Core.

Select one of the following links for breaking changes in a specific version:

The following breaking changes in ASP.NET Core 3.0, 3.1, and 5.0 are documented on this page:

ASP.NET Core 5.0

Authentication: AzureAD.UI and AzureADB2C.UI APIs and packages marked obsolete

In ASP.NET Core 2.1, integration with Azure Active Directory (Azure AD) and Azure Active Directory B2C (Azure AD B2C) authentication is provided by the Microsoft.AspNetCore.Authentication.AzureAD.UI and Microsoft.AspNetCore.Authentication.AzureADB2C.UI packages. The functionality provided by these packages is based on the Azure AD v1.0 endpoint.

In ASP.NET Core 5.0 and later, integration with Azure AD and Azure AD B2C authentication is provided by the Microsoft.Identity.Web package. This package is based on the Microsoft Identity Platform, which is formerly known as the Azure AD v2.0 endpoint. Consequently, the old APIs in the Microsoft.AspNetCore.Authentication.AzureAD.UI and Microsoft.AspNetCore.Authentication.AzureADB2C.UI packages were deprecated.

For discussion, see GitHub issue dotnet/aspnetcore#25807.

Version introduced

5.0 Preview 8

Old behavior

The APIs weren't marked as obsolete.

New behavior

The APIs are marked as obsolete.

Reason for change

The Azure AD and Azure AD B2C authentication functionality was migrated to Microsoft Authentication Library (MSAL) APIs that are provided by Microsoft.Identity.Web.

Follow the Microsoft.Identity.Web API guidance for web apps and web APIs.

Category

ASP.NET Core

Affected APIs


Authorization: Resource in endpoint routing is HttpContext

When using endpoint routing in ASP.NET Core 3.1, the resource used for authorization is the endpoint. This approach was insufficient for gaining access to the route data (RouteData). Previously in MVC, an HttpContext resource was passed in, which allows access to both the endpoint (Endpoint) and the route data. This change ensures that the resource passed to authorization is always the HttpContext.

Version introduced

5.0 Preview 7

Old behavior

When using endpoint routing and the authorization middleware (AuthorizationMiddleware) or [Authorize] attributes, the resource passed to authorization is the matching endpoint.

New behavior

Endpoint routing passes the HttpContext to authorization.

Reason for change

You can get to the endpoint from the HttpContext. However, there was no way to get from the endpoint to things like the route data. There was a loss in functionality from non-endpoint routing.

If your app uses the endpoint resource, call GetEndpoint on the HttpContext to continue accessing the endpoint.

In ASP.NET Core 5.0 Preview 8 and later, you can revert to the old behavior with SetSwitch. For example:

AppContext.SetSwitch(
    "Microsoft.AspNetCore.Authorization.SuppressUseHttpContextAsAuthorizationResource",
    isEnabled: true);

Category

ASP.NET Core

Affected APIs

None


Azure: Microsoft-prefixed Azure integration packages removed

The following Microsoft.* packages that provide integration between ASP.NET Core and Azure SDKs aren't included in ASP.NET Core 5.0:

For discussion on this issue, see dotnet/aspnetcore#19570.

Version introduced

5.0 Preview 1

Old behavior

The Microsoft.* packages integrated Azure services with the Configuration and Data Protection APIs.

New behavior

New Azure.* packages integrate Azure services with the Configuration and Data Protection APIs.

Reason for change

The change was made because the Microsoft.* packages were:

  • Using outdated versions of the Azure SDK. Simple updates weren't possible because the new versions of the Azure SDK included breaking changes.
  • Tied to the .NET Core release schedule. Transferring ownership of the packages to the Azure SDK team enables package updates as the Azure SDK is updated.

In ASP.NET Core 2.1 or later projects, replace the old Microsoft.* with the new Azure.* packages.

Old New
Microsoft.AspNetCore.DataProtection.AzureKeyVault Azure.Extensions.AspNetCore.DataProtection.Keys
Microsoft.AspNetCore.DataProtection.AzureStorage Azure.Extensions.AspNetCore.DataProtection.Blobs
Microsoft.Extensions.Configuration.AzureKeyVault Azure.Extensions.AspNetCore.Configuration.Secrets

The new packages use a new version of the Azure SDK that includes breaking changes. The general usage patterns are unchanged. Some overloads and options may differ to adapt to changes in the underlying Azure SDK APIs.

The old packages will:

  • Be supported by the ASP.NET Core team for the lifetime of .NET Core 2.1 and 3.1.
  • Not be included in .NET 5.

When upgrading your project to .NET 5, transition to the Azure.* packages to maintain support.

Category

ASP.NET Core

Affected APIs


BinaryFormatter serialization methods are obsolete and prohibited in ASP.NET apps

Serialize and Deserialize methods on BinaryFormatter, Formatter, and IFormatter are now obsolete as warning. Additionally, BinaryFormatter serialization is prohibited by default for ASP.NET apps.

Change description

Due to security vulnerabilities in BinaryFormatter, the following methods are now obsolete and produce a compile-time warning with ID SYSLIB0011. Additionally, in ASP.NET Core 5.0 and later apps, they will throw a NotSupportedException, unless the web app has re-enabled BinaryFormatter functionality.

The following serialization methods are also obsolete and produce warning SYSLIB0011, but have no behavioral changes:

Version introduced

5.0 Preview 8

Reason for change

These methods are marked obsolete as part of an effort to wind down usage of BinaryFormatter within the .NET ecosystem.

  • Stop using BinaryFormatter in your code. Instead, consider using JsonSerializer or XmlSerializer. For more information, see BinaryFormatter security guide.

  • You can temporarily suppress the BinaryFormatter compile-time warning, which is SYSLIB0011. We recommend that you thoroughly assess your code for risks before choosing this option. The easiest way to suppress the warnings is to surround the individual call site with #pragma directives.

    // Now read the purchase order back from disk
    using (var readStream = new FileStream("myfile.bin", FileMode.Open))
    {
        var formatter = new BinaryFormatter();
    #pragma warning disable SYSLIB0011
        return (PurchaseOrder)formatter.Deserialize(readStream);
    #pragma warning restore SYSLIB0011
    }
    

    You can also suppress the warning in the project file.

    <PropertyGroup>
      <OutputType>Exe</OutputType>
      <TargetFramework>net5.0</TargetFramework>
      <!-- Disable "BinaryFormatter is obsolete" warnings for entire project -->
      <NoWarn>$(NoWarn);SYSLIB0011</NoWarn>
    </PropertyGroup>
    

    If you suppress the warning in the project file, the warning is suppressed for all code files in the project. Suppressing SYSLIB0011 does not suppress warnings caused by using other obsolete APIs.

  • To continue using BinaryFormatter in ASP.NET apps, you can re-enable it in the project file. However, it's strongly recommended not to do this. For more information, see BinaryFormatter security guide.

    <PropertyGroup>
      <TargetFramework>net5.0</TargetFramework>
      <!-- Warning: Setting the following switch is *NOT* recommended in web apps. -->
      <EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
    </PropertyGroup>
    

For more information about recommended actions, see Resolving BinaryFormatter obsoletion and disablement errors.

Category

  • Core .NET libraries
  • ASP.NET

Affected APIs


Blazor: Insignificant whitespace trimmed from components at compile time

Starting with ASP.NET Core 5.0 Preview 7, the Razor compiler omits insignificant whitespace in Blazor components (.razor files) at compile time. For discussion, see issue dotnet/aspnetcore#23568.

Version introduced

5.0 Preview 7

Old behavior

In 3.x versions of Blazor Server and Blazor WebAssembly, whitespace is honored in a component's source code. Whitespace-only text nodes render in the browser's Document Object Model (DOM) even when there's no visual effect.

Consider the following Blazor component code:

<ul>
    @foreach (var item in Items)
    {
        <li>
            @item.Text
        </li>
    }
</ul>

The preceding example renders two whitespace nodes:

  • Outside of the @foreach code block.
  • Around the <li> element.
  • Around the @item.Text output.

A list containing 100 items results in 402 whitespace nodes. That's over half of all nodes rendered, even though none of the whitespace nodes visually affect the rendered output.

When rendering static HTML for components, whitespace inside a tag wasn't preserved. For example, view the source of the following component:

<foo        bar="baz"     />

Whitespace isn't preserved. The pre-rendered output is:

<foo bar="baz" />

New behavior

Unless the @preservewhitespace directive is used with value true, whitespace nodes are removed if they:

  • Are leading or trailing within an element.
  • Are leading or trailing within a RenderFragment parameter. For example, child content being passed to another component.
  • Precede or follow a C# code block such as @if and @foreach.

Reason for change

A goal for Blazor in ASP.NET Core 5.0 is to improve the performance of rendering and diffing. Insignificant whitespace tree nodes consumed up to 40 percent of the rendering time in benchmarks.

In most cases, the visual layout of the rendered component is unaffected. However, the whitespace removal might affect the rendered output when using a CSS rule like white-space: pre. To disable this performance optimization and preserve the whitespace, take one of the following actions:

  • Add the @preservewhitespace true directive at the top of the .razor file to apply the preference to a specific component.
  • Add the @preservewhitespace true directive inside an _Imports.razor file to apply the preference to an entire subdirectory or the entire project.

In most cases, no action is required, as applications will typically continue to behave normally (but faster). If the whitespace stripping causes any problems for a particular component, use @preservewhitespace true in that component to disable this optimization.

Category

ASP.NET Core

Affected APIs

None


Blazor: JSObjectReference and JSInProcessObjectReference types changed to internal

The new Microsoft.JSInterop.JSObjectReference and Microsoft.JSInterop.JSInProcessObjectReference types introduced in ASP.NET Core 5.0 RC1 have been marked as internal.

Version introduced

5.0 RC2

Old behavior

A JSObjectReference can be obtained from a JavaScript interop call via IJSRuntime. For example:

var jsObjectReference = await JSRuntime.InvokeAsync<JSObjectReference>(...);

New behavior

JSObjectReference uses the internal access modifier. The public IJSObjectReference interface must be used instead. For example:

var jsObjectReference = await JSRuntime.InvokeAsync<IJSObjectReference>(...);

JSInProcessObjectReference was also marked as internal and was replaced by IJSInProcessObjectReference.

Reason for change

The change makes the JavaScript interop feature more consistent with other patterns within Blazor. IJSObjectReference is analogous to IJSRuntime in that it serves a similar purpose and has similar methods and extensions.

Replace occurrences of JSObjectReference and JSInProcessObjectReference with IJSObjectReference and IJSInProcessObjectReference, respectively.

Category

ASP.NET Core

Affected APIs

  • Microsoft.JSInterop.JSObjectReference
  • Microsoft.JSInterop.JSInProcessObjectReference

Blazor: ProtectedBrowserStorage feature moved to shared framework

As part of the ASP.NET Core 5.0 RC2 release, the ProtectedBrowserStorage feature moved to the ASP.NET Core shared framework.

Version introduced

5.0 RC2

Old behavior

In ASP.NET Core 5.0 Preview 8, the feature is available as a part of the Microsoft.AspNetCore.Components.Web.Extensions package but was only usable in Blazor WebAssembly.

In ASP.NET Core 5.0 RC1, the feature is available as part of the Microsoft.AspNetCore.Components.ProtectedBrowserStorage package, which references the Microsoft.AspNetCore.App shared framework.

New behavior

In ASP.NET Core 5.0 RC2, a NuGet package reference is no longer needed to reference and use the feature.

Reason for change

The move to the shared framework is a better fit for the user experience customers expect.

If upgrading from ASP.NET Core 5.0 RC1, complete the following steps:

  1. Remove the Microsoft.AspNetCore.Components.ProtectedBrowserStorage package reference from the project.
  2. Replace using Microsoft.AspNetCore.Components.ProtectedBrowserStorage; with using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;.
  3. Remove the call to AddProtectedBrowserStorage from your Startup class.

If upgrading from ASP.NET Core 5.0 Preview 8, complete the following steps:

  1. Remove the Microsoft.AspNetCore.Components.Web.Extensions package reference from the project.
  2. Replace using Microsoft.AspNetCore.Components.Web.Extensions; with using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;.
  3. Remove the call to AddProtectedBrowserStorage from your Startup class.

Category

ASP.NET Core

Affected APIs

None


Blazor: RenderTreeFrame readonly public fields have become properties

In ASP.NET Core 3.0 and 3.1, the RenderTreeFrame struct exposed various readonly public fields, including FrameType, Sequence, and others. In ASP.NET Core 5.0 RC1 and later versions, all the readonly public fields changed to readonly public properties.

This change won't affect many developers because:

  • Any app or library that simply uses .razor files (or even manual RenderTreeBuilder calls) to define its components wouldn't be referencing this type directly.
  • The RenderTreeFrame type itself is regarded as an implementation detail, not intended for use outside of the framework. ASP.NET Core 3.0 and later includes an analyzer that issues compiler warnings if the type is being used directly.
  • Even if you reference RenderTreeFrame directly, this change is binary-breaking but not source-breaking. That is, your existing source code will compile and behave properly. You'll only encounter an issue if compiling against a .NET Core 3.x framework and then running those binaries against the .NET 5.0 RC1 and later framework.

For discussion, see GitHub issue dotnet/aspnetcore#25727.

Version introduced

5.0 RC1

Old behavior

Public members on RenderTreeFrame are defined as fields. For example, renderTreeFrame.Sequence and renderTreeFrame.ElementName.

New behavior

Public members on RenderTreeFrame are defined as properties with the same names as before. For example, renderTreeFrame.Sequence and renderTreeFrame.ElementName.

If older precompiled code hasn't been recompiled since this change, it may throw an exception similar to MissingFieldException: Field not found: 'Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrame.FrameType'.

Reason for change

This change was necessary to implement high-impact performance improvements in Blazor component rendering in ASP.NET Core 5.0. The same levels of safety and encapsulation are maintained.

Most Blazor developers are unaffected by this change. The change is more likely to affect library and package authors, but only in rare cases. Specifically, if you're developing:

  • An app and using ASP.NET Core 3.x or upgrading to 5.0 RC1 or later, you don't need to change your own code. However, if you depend on a library that upgraded to account for this change, then you need to update to a newer version of that library.
  • A library and want to support only ASP.NET Core 5.0 RC1 or later, no action is needed. Just ensure that your project file declares a <TargetFramework> value of net5.0 or a later version.
  • A library and want to support both ASP.NET Core 3.x and 5.0, determine whether your code reads any RenderTreeFrame members. For example, evaluating someRenderTreeFrame.FrameType.
    • Most libraries won't read RenderTreeFrame members, including libraries that contain .razor components. In this case, no action is needed.
    • However, if your library does that, you'll need to multi-target to support both netstandard2.1 and net5.0. Apply the following changes in your project file:
      • Replace the existing <TargetFramework> element with <TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>.

      • Use a conditional Microsoft.AspNetCore.Components package reference to account for both versions you wish to support. For example:

        <PackageReference Include="Microsoft.AspNetCore.Components" Version="3.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
        <PackageReference Include="Microsoft.AspNetCore.Components" Version="5.0.0-rc.1.*" Condition="'$(TargetFramework)' != 'netstandard2.0'" />
        

For further clarification, see this diff showing how @jsakamoto already upgraded the Toolbelt.Blazor.HeadElement library.

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrame


Blazor: Target framework of NuGet packages changed

Blazor 3.2 WebAssembly projects were compiled to target .NET Standard 2.1 (<TargetFramework>netstandard2.1</TargetFramework>). In ASP.NET Core 5.0, both Blazor Server and Blazor WebAssembly projects target .NET 5.0 (<TargetFramework>net5.0</TargetFramework>). To better align with the target framework change, the following Blazor packages no longer target .NET Standard 2.1:

For discussion, see GitHub issue dotnet/aspnetcore#23424.

Version introduced

5.0 Preview 7

Old behavior

In Blazor 3.1 and 3.2, packages target .NET Standard 2.1 and .NET Core 3.1.

New behavior

In ASP.NET Core 5.0, packages target .NET 5.0.

Reason for change

The change was made to better align with .NET target framework requirements.

Blazor 3.2 WebAssembly projects should target .NET 5.0 as part of updating their package references to 5.x.x. Libraries that reference one of these packages can either target .NET 5.0 or multi-target depending on their requirements.

Category

ASP.NET Core

Affected APIs

None


Blazor: Updated browser support

ASP.NET Core 5.0 introduces new Blazor features, some of which are incompatible with older browsers. The list of browsers supported by Blazor in ASP.NET Core 5.0 has been updated accordingly.

For discussion, see GitHub issue dotnet/aspnetcore#26475.

Version introduced

5.0

Old behavior

Blazor Server supports Microsoft Internet Explorer 11 with sufficient polyfills. Blazor Server and Blazor WebAssembly are also functional in Microsoft Edge Legacy.

New behavior

Blazor Server in ASP.NET Core 5.0 isn't supported with Microsoft Internet Explorer 11. Blazor Server and Blazor WebAssembly aren't fully functional in Microsoft Edge Legacy.

Reason for change

New Blazor features in ASP.NET Core 5.0 are incompatible with these older browsers, and use of these older browsers is diminishing. For more information, see the following resources:

Upgrade from these older browsers to the new, Chromium-based Microsoft Edge. For Blazor apps that need to support these older browsers, use ASP.NET Core 3.1. The supported browsers list for Blazor in ASP.NET Core 3.1 hasn't changed and is documented at Supported platforms.

Category

ASP.NET Core

Affected APIs

None


Extensions: Package reference changes affecting some NuGet packages

With the migration of some Microsoft.Extensions.* NuGet packages from the dotnet/extensions repository to dotnet/runtime, as described in aspnet/Announcements#411, packaging changes are being applied to some of the migrated packages. For discussion on this issue, see dotnet/aspnetcore#21033.

Version introduced

5.0 Preview 4

Old behavior

Some Microsoft.Extensions.* packages included package references for APIs on which your app relied.

New behavior

Your app may have to add Microsoft.Extensions.* package dependencies.

Reason for change

Packaging policies were updated to better align with the dotnet/runtime repository. Under the new policy, unused package references are removed from .nupkg files during packaging.

Consumers of the affected packages should add a direct dependency on the removed package dependency in their project if APIs from removed package dependency are used. The following table lists the affected packages and the corresponding changes.

Package name Change description
Microsoft.Extensions.Configuration.Binder Removed reference to Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Json Removed reference to System.Threading.Tasks.Extensions
Microsoft.Extensions.Hosting.Abstractions Removed reference to Microsoft.Extensions.Logging.Abstractions
Microsoft.Extensions.Logging Removed reference to Microsoft.Extensions.Configuration.Binder
Microsoft.Extensions.Logging.Console Removed reference to Microsoft.Extensions.Configuration.Abstractions
Microsoft.Extensions.Logging.EventLog Removed reference to System.Diagnostics.EventLog for the .NET Framework 4.6.1 target framework moniker
Microsoft.Extensions.Logging.EventSource Removed reference to System.Threading.Tasks.Extensions
Microsoft.Extensions.Options Removed reference to System.ComponentModel.Annotations

For example, the package reference to Microsoft.Extensions.Configuration was removed from Microsoft.Extensions.Configuration.Binder. No API from the dependency was used in the package. Users of Microsoft.Extensions.Configuration.Binder who depend on APIs from Microsoft.Extensions.Configuration should add a direct reference to it in their project.

Category

ASP.NET Core

Affected APIs

None


HTTP: HttpClient instances created by IHttpClientFactory log integer status codes

HttpClient instances created by IHttpClientFactory log HTTP status codes as integers instead of with status code names.

Version introduced

5.0 Preview 1

Old behavior

Logging uses the textual descriptions of HTTP status codes. Consider the following log messages:

Received HTTP response after 56.0044ms - OK
End processing HTTP request after 70.0862ms - OK

New behavior

Logging uses the integer values of HTTP status codes. Consider the following log messages:

Received HTTP response after 56.0044ms - 200
End processing HTTP request after 70.0862ms - 200

Reason for change

The original behavior of this logging is inconsistent with other parts of ASP.NET Core that have always used integer values. The inconsistency makes logs difficult to query via structured logging systems such as Elasticsearch. For more context, see dotnet/extensions#1549.

Using integer values is more flexible than text because it allows queries on ranges of values.

Adding another log value to capture the integer status code was considered. Unfortunately, doing so would introduce another inconsistency with the rest of ASP.NET Core. HttpClient logging and HTTP server/hosting logging use the same StatusCode key name already.

The best option is to update logging queries to use the integer values of status codes. This option may cause some difficulty writing queries across multiple ASP.NET Core versions. However, using integers for this purpose is much more flexible for querying logs.

If you need to force compatibility with the old behavior and use textual status codes, replace the IHttpClientFactory logging with your own:

  1. Copy the .NET Core 3.1 versions of the following classes into your project:

  2. Rename the classes to avoid conflicts with public types in the Microsoft.Extensions.Http NuGet package.

  3. Replace the built-in implementation of LoggingHttpMessageHandlerBuilderFilter with your own in the project's Startup.ConfigureServices method. For example:

    public void ConfigureServices(IServiceCollection services)
    {
        // Other service registrations go first. Code omitted for brevity.
    
        // Place the following after all AddHttpClient registrations.
        services.RemoveAll<IHttpMessageHandlerBuilderFilter>();
    
        services.AddSingleton<IHttpMessageHandlerBuilderFilter,
                              MyLoggingHttpMessageHandlerBuilderFilter>();
    }
    

Category

ASP.NET Core

Affected APIs

System.Net.Http.HttpClient


HTTP: Kestrel and IIS BadHttpRequestException types marked obsolete and replaced

Microsoft.AspNetCore.Server.Kestrel.BadHttpRequestException and Microsoft.AspNetCore.Server.IIS.BadHttpRequestException have been marked obsolete and changed to derive from Microsoft.AspNetCore.Http.BadHttpRequestException. The Kestrel and IIS servers still throw their old exception types for backwards compatibility. The obsolete types will be removed in a future release.

For discussion, see dotnet/aspnetcore#20614.

Version introduced

5.0 Preview 4

Old behavior

Microsoft.AspNetCore.Server.Kestrel.BadHttpRequestException and Microsoft.AspNetCore.Server.IIS.BadHttpRequestException derived from System.IO.IOException.

New behavior

Microsoft.AspNetCore.Server.Kestrel.BadHttpRequestException and Microsoft.AspNetCore.Server.IIS.BadHttpRequestException are obsolete. The types also derive from Microsoft.AspNetCore.Http.BadHttpRequestException, which derives from System.IO.IOException.

Reason for change

The change was made to:

  • Consolidate duplicate types.
  • Unify behavior across server implementations.

An app can now catch the base exception Microsoft.AspNetCore.Http.BadHttpRequestException when using either Kestrel or IIS.

Replace usages of Microsoft.AspNetCore.Server.Kestrel.BadHttpRequestException and Microsoft.AspNetCore.Server.IIS.BadHttpRequestException with Microsoft.AspNetCore.Http.BadHttpRequestException.

Category

ASP.NET Core

Affected APIs


HttpSys: Client certificate renegotiation disabled by default

The option to renegotiate a connection and request a client certificate has been disabled by default. For discussion, see issue dotnet/aspnetcore#23181.

Version introduced

ASP.NET Core 5.0

Old behavior

The connection can be renegotiated to request a client certificate.

New behavior

Client certificates can only be requested during the initial connection handshake. For more information, see pull request dotnet/aspnetcore#23162.

Reason for change

Renegotiation caused a number of performance and deadlock issues. It's also not supported in HTTP/2. For additional context from when the option to control this behavior was introduced in ASP.NET Core 3.1, see issue dotnet/aspnetcore#14806.

Apps that require client certificates should use netsh.exe to set the clientcertnegotiation option to enabled. For more information, see netsh http commands.

If you want client certificates enabled for only some parts of your app, see the guidance at Optional client certificates.

If you need the old renegotiate behavior, set HttpSysOptions.ClientCertificateMethod to the old value ClientCertificateMethod.AllowRenegotiate. This isn't recommended for the reasons outlined above and in the linked guidance.

Category

ASP.NET Core

Affected APIs


IIS: UrlRewrite middleware query strings are preserved

An IIS UrlRewrite middleware defect prevented the query string from being preserved in rewrite rules. That defect has been fixed to maintain consistency with the IIS UrlRewrite Module's behavior.

For discussion, see issue dotnet/aspnetcore#22972.

Version introduced

ASP.NET Core 5.0 Preview 7

Old behavior

Consider the following rewrite rule:

<rule name="MyRule" stopProcessing="true">
  <match url="^about" />
  <action type="Redirect" url="/contact" redirectType="Temporary" appendQueryString="true" />
</rule>

The preceding rule doesn't append the query string. A URI like /about?id=1 redirects to /contact instead of /contact?id=1. The appendQueryString attribute defaults to true as well.

New behavior

The query string is preserved. The URI from the example in Old behavior would be /contact?id=1.

Reason for change

The old behavior didn't match the IIS UrlRewrite Module's behavior. To support porting between the middleware and module, the goal is to maintain consistent behaviors.

If the behavior of removing the query string is preferred, set the action element to appendQueryString="false".

Category

ASP.NET Core

Affected APIs

IISUrlRewriteOptionsExtensions.AddIISUrlRewrite


Kestrel: Configuration changes at run time detected by default

Kestrel now reacts to changes made to the Kestrel section of the project's IConfiguration instance (for example, appsettings.json) at run time. To learn more about how to configure Kestrel using appsettings.json, see the appsettings.json example in Endpoint configuration.

Kestrel will bind, unbind, and rebind endpoints as necessary to react to these configuration changes.

For discussion, see issue dotnet/aspnetcore#22807.

Version introduced

5.0 Preview 7

Old behavior

Before ASP.NET Core 5.0 Preview 6, Kestrel didn't support changing configuration at run time.

In ASP.NET Core 5.0 Preview 6, you could opt into the now-default behavior of reacting to configuration changes at run time. Opting in required binding Kestrel's configuration manually:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args) =>
        CreateHostBuilder(args).Build().Run();

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseKestrel((builderContext, kestrelOptions) =>
                {
                    kestrelOptions.Configure(
                        builderContext.Configuration.GetSection("Kestrel"), reloadOnChange: true);
                });

                webBuilder.UseStartup<Startup>();
            });
}

New behavior

Kestrel reacts to configuration changes at run time by default. To support that change, ConfigureWebHostDefaults calls KestrelServerOptions.Configure(IConfiguration, bool) with reloadOnChange: true by default.

Reason for change

The change was made to support endpoint reconfiguration at run time without completely restarting the server. Unlike with a full server restart, unchanged endpoints aren't unbound even temporarily.

  • For most scenarios in which Kestrel's default configuration section doesn't change at run time, this change has no impact and no action is needed.

  • For scenarios in which Kestrel's default configuration section does change at run time and Kestrel should react to it, this is now the default behavior.

  • For scenarios in which Kestrel's default configuration section changes at run time and Kestrel shouldn't react to it, you can opt out as follows:

    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Hosting;
    
    public class Program
    {
        public static void Main(string[] args) =>
            CreateHostBuilder(args).Build().Run();
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseKestrel((builderContext, kestrelOptions) =>
                    {
                        kestrelOptions.Configure(
                            builderContext.Configuration.GetSection("Kestrel"), reloadOnChange: false);
                    });
    
                    webBuilder.UseStartup<Startup>();
                });
    }
    

Notes:

This change doesn't modify the behavior of the KestrelServerOptions.Configure(IConfiguration) overload, which still defaults to the reloadOnChange: false behavior.

It's also important to make sure the configuration source supports reloading. For JSON sources, reloading is configured by calling AddJsonFile(path, reloadOnChange: true). Reloading is already configured by default for appsettings.json and appsettings.{Environment}.json.

Category

ASP.NET Core

Affected APIs

GenericHostBuilderExtensions.ConfigureWebHostDefaults


Kestrel: Default supported TLS protocol versions changed

Kestrel now uses the system default TLS protocol versions rather than restricting connections to the TLS 1.1 and TLS 1.2 protocols like it did previously.

This change allows:

  • TLS 1.3 to be used by default in environments that support it.
  • TLS 1.0 to be used in some environments (such as Windows Server 2016 by default), which is usually not desirable.

For discussion, see issue dotnet/aspnetcore#22563.

Version introduced

5.0 Preview 6

Old behavior

Kestrel required that connections use TLS 1.1 or TLS 1.2 by default.

New behavior

Kestrel allows the operating system to choose the best protocol to use and to block insecure protocols. HttpsConnectionAdapterOptions.SslProtocols now defaults to SslProtocols.None instead of SslProtocols.Tls12 | SslProtocols.Tls11.

Reason for change

The change was made to support TLS 1.3 and future TLS versions by default as they become available.

Unless your app has a specific reason not to, you should use the new defaults. Verify your system is configured to allow only secure protocols.

To disable older protocols, take one of the following actions:

  • Disable older protocols, such as TLS 1.0, system-wide with the Windows instructions. It's currently enabled by default on all Windows versions.

  • Manually select which protocols you want to support in code as follows:

    using System.Security.Authentication;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Hosting;
    
    public class Program
    {
        public static void Main(string[] args) =>
            CreateHostBuilder(args).Build().Run();
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseKestrel(kestrelOptions =>
                    {
                        kestrelOptions.ConfigureHttpsDefaults(httpsOptions =>
                        {
                            httpsOptions.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13;
                        });
                    });
    
                    webBuilder.UseStartup<Startup>();
                });
    }
    

Unfortunately, there's no API to exclude specific protocols.

Category

ASP.NET Core

Affected APIs

HttpsConnectionAdapterOptions.SslProtocols


Kestrel: HTTP/2 disabled over TLS on incompatible Windows versions

To enable HTTP/2 over Transport Layer Security (TLS) on Windows, two requirements need to be met:

  • Application-Layer Protocol Negotiation (ALPN) support, which is available starting with Windows 8.1 and Windows Server 2012 R2.
  • A set of ciphers compatible with HTTP/2, which is available starting with Windows 10 and Windows Server 2016.

As such, Kestrel's behavior when HTTP/2 over TLS is configured has changed to:

  • Downgrade to Http1 and log a message at the Information level when ListenOptions.HttpProtocols is set to Http1AndHttp2. Http1AndHttp2 is the default value for ListenOptions.HttpProtocols.
  • Throw a NotSupportedException when ListenOptions.HttpProtocols is set to Http2.

For discussion, see issue dotnet/aspnetcore#23068.

Version introduced

ASP.NET Core 5.0 Preview 7

Old behavior

The following table outlines the behavior when HTTP/2 over TLS is configured.

Protocols Windows 7,
Windows Server 2008 R2,
or earlier
Windows 8,
Windows Server 2012
Windows 8.1,
Windows Server 2012 R2
Windows 10,
Windows Server 2016,
or newer
Http2 Throw NotSupportedException Error during TLS handshake Error during TLS handshake * No error
Http1AndHttp2 Downgrade to Http1 Downgrade to Http1 Error during TLS handshake * No error

* Configure compatible cipher suites to enable these scenarios.

New behavior

The following table outlines the behavior when HTTP/2 over TLS is configured.

Protocols Windows 7,
Windows Server 2008 R2,
or earlier
Windows 8,
Windows Server 2012
Windows 8.1,
Windows Server 2012 R2
Windows 10,
Windows Server 2016,
or newer
Http2 Throw NotSupportedException Throw NotSupportedException Throw NotSupportedException ** No error
Http1AndHttp2 Downgrade to Http1 Downgrade to Http1 Downgrade to Http1 ** No error

** Configure compatible cipher suites and set the app context switch Microsoft.AspNetCore.Server.Kestrel.EnableWindows81Http2 to true to enable these scenarios.

Reason for change

This change ensures compatibility errors for HTTP/2 over TLS on older Windows versions are surfaced as early and as clearly as possible.

Ensure HTTP/2 over TLS is disabled on incompatible Windows versions. Windows 8.1 and Windows Server 2012 R2 are incompatible since they lack the necessary ciphers by default. However, it's possible to update the Computer Configuration settings to use HTTP/2 compatible ciphers. For more information, see TLS cipher suites in Windows 8.1. Once configured, HTTP/2 over TLS on Kestrel must be enabled by setting the app context switch Microsoft.AspNetCore.Server.Kestrel.EnableWindows81Http2. For example:

AppContext.SetSwitch("Microsoft.AspNetCore.Server.Kestrel.EnableWindows81Http2", true);

No underlying support has changed. For example, HTTP/2 over TLS has never worked on Windows 8 or Windows Server 2012. This change modifies how errors in these unsupported scenarios are presented.

Category

ASP.NET Core

Affected APIs

None


Kestrel: Libuv transport marked as obsolete

Earlier versions of ASP.NET Core used Libuv as an implementation detail of how asynchronous input and output was performed. In ASP.NET Core 2.0, an alternative, Socket-based transport was developed. In ASP.NET Core 2.1, Kestrel switched to using the Socket-based transport by default. Libuv support was maintained for compatibility reasons.

At this point, use of the Socket-based transport is far more common than the Libuv transport. Consequently, Libuv support is marked as obsolete in .NET 5.0 and will be removed entirely in .NET 6.0.

As part of this change, Libuv support for new operating system platforms (like Windows ARM64) won't be added in the .NET 5.0 timeframe.

For discussion on blocking issues that require the use of the Libuv transport, see the GitHub issue at dotnet/aspnetcore#23409.

Version introduced

5.0 Preview 8

Old behavior

The Libuv APIs aren't marked as obsolete.

New behavior

The Libuv APIs are marked as obsolete.

Reason for change

The Socket-based transport is the default. There aren't any compelling reasons to continue using the Libuv transport.

Discontinue use of the Libuv package and extension methods.

Category

ASP.NET Core

Affected APIs


Localization: "Pubternal" APIs removed

To better maintain the public API surface of ASP.NET Core, some "pubternal" localization APIs were removed. A "pubternal" API has a public access modifier and is defined in a namespace that implies an internal intent.

For discussion, see dotnet/aspnetcore#22291.

Version introduced

5.0 Preview 6

Old behavior

The following APIs were public:

  • Microsoft.Extensions.Localization.Internal.AssemblyWrapper
  • Microsoft.Extensions.Localization.Internal.IResourceStringProvider
  • Microsoft.Extensions.Localization.ResourceManagerStringLocalizer constructor overloads accepting either of the following parameter types:
    • AssemblyWrapper
    • IResourceStringProvider

New behavior

The following list outlines the changes:

  • Microsoft.Extensions.Localization.Internal.AssemblyWrapper became Microsoft.Extensions.Localization.AssemblyWrapper and is now internal.
  • Microsoft.Extensions.Localization.Internal.IResourceStringProvider became Microsoft.Extensions.Localization.Internal.IResourceStringProvider and is now internal.
  • Microsoft.Extensions.Localization.ResourceManagerStringLocalizer constructor overloads accepting either of the following parameter types are now internal:
    • AssemblyWrapper
    • IResourceStringProvider

Reason for change

Explained more thoroughly at aspnet/Announcements#377, "pubternal" types were removed from the public API surface. These changes adapt more classes to that design decision. The classes in question were intended as extension points for the team's internal testing.

Although it's unlikely, some apps may intentionally or accidentally depend upon the "pubternal" types. See the New behavior sections to determine how to migrate away from the types.

If you've identified a scenario which the public API allowed before this change but doesn't now, file an issue at dotnet/aspnetcore.

Category

ASP.NET Core

Affected APIs


Localization: Obsolete constructor removed in request localization middleware

The RequestLocalizationMiddleware constructor that lacks an ILoggerFactory parameter was marked as obsolete in this commit. In ASP.NET Core 5.0, the obsolete constructor was removed. For discussion, see dotnet/aspnetcore#23785.

Version introduced

5.0 Preview 8

Old behavior

The obsolete RequestLocalizationMiddleware.ctor(RequestDelegate, IOptions<RequestLocalizationOptions>) constructor exists.

New behavior

The obsolete RequestLocalizationMiddleware.ctor(RequestDelegate, IOptions<RequestLocalizationOptions>) constructor doesn't exist.

Reason for change

This change ensures that the request localization middleware always has access to a logger.

When manually constructing an instance of RequestLocalizationMiddleware, pass an ILoggerFactory instance in the constructor. If a valid ILoggerFactory instance isn't available in that context, consider passing the middleware constructor a NullLoggerFactory instance.

Category

ASP.NET Core

Affected APIs

RequestLocalizationMiddleware.ctor(RequestDelegate, IOptions<RequestLocalizationOptions>)


Localization: ResourceManagerWithCultureStringLocalizer class and WithCulture interface member removed

The ResourceManagerWithCultureStringLocalizer class and WithCulture method were removed in .NET 5.0 Preview 1.

For context, see aspnet/Announcements#346 and dotnet/aspnetcore#3324. For discussion on this change, see dotnet/aspnetcore#7756.

Version introduced

5.0 Preview 1

Old behavior

The ResourceManagerWithCultureStringLocalizer class and the ResourceManagerStringLocalizer.WithCulture method are obsolete in .NET Core 3.0 Preview 3 and later.

New behavior

The ResourceManagerWithCultureStringLocalizer class and the ResourceManagerStringLocalizer.WithCulture method have been removed in .NET 5.0 Preview 1. For an inventory of the changes made, see the pull request at dotnet/extensions#2562.

Reason for change

The ResourceManagerWithCultureStringLocalizer class and ResourceManagerStringLocalizer.WithCulture method were often sources of confusion for users of localization. The confusion was especially high when creating a custom IStringLocalizer implementation. This class and method give consumers the impression that an IStringLocalizer instance is expected to be "per-language, per-resource". In reality, the instance should only be "per-resource". At run time, the CultureInfo.CurrentUICulture property determines the language to be used.

Stop using the ResourceManagerWithCultureStringLocalizer class and the ResourceManagerStringLocalizer.WithCulture method.

Category

ASP.NET Core

Affected APIs


Middleware: Database error page marked as obsolete

The DatabaseErrorPageMiddleware and its associated extension methods were marked as obsolete in ASP.NET Core 5.0. The middleware and extension methods will be removed in ASP.NET Core 6.0. The functionality will instead be provided by DatabaseDeveloperPageExceptionFilter and its extension methods.

For discussion, see the GitHub issue at dotnet/aspnetcore#24987.

Version introduced

5.0 RC 1

Old behavior

DatabaseErrorPageMiddleware and its associated extension methods weren't obsolete.

New behavior

DatabaseErrorPageMiddleware and its associated extension methods are obsolete.

Reason for change

DatabaseErrorPageMiddleware was migrated to an extensible API for the developer exception page. For more information on the extensible API, see GitHub issue dotnet/aspnetcore#8536.

Complete the following steps:

  1. Stop using DatabaseErrorPageMiddleware in your project. For example, remove the UseDatabaseErrorPage method call from Startup.Configure:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDatabaseErrorPage();
        }
    }
    
  2. Add the developer exception page to your project. For example, call the UseDeveloperExceptionPage method in Startup.Configure:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    }
    
  3. Add the Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore NuGet package to the project file.

  4. Add the database developer page exception filter to the services collection. For example, call the AddDatabaseDeveloperPageExceptionFilter method in Startup.ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDatabaseDeveloperPageExceptionFilter();
    }
    

Category

ASP.NET Core

Affected APIs


Middleware: Exception Handler Middleware throws original exception if handler not found

Before ASP.NET Core 5.0, the Exception Handler Middleware executes the configured exception handler when an exception has occurred. If the exception handler, configured via ExceptionHandlingPath, can't be found, an HTTP 404 response is produced. The response is misleading in that it:

  • Seems to be a user error.
  • Obscures the fact that an exception occurred on the server.

To address the misleading error in ASP.NET Core 5.0, the ExceptionHandlerMiddleware throws the original exception if the exception handler can't be found. As a result, an HTTP 500 response is produced by the server. The response will be easier to examine in the server logs when debugging the error that occurred.

For discussion, see GitHub issue dotnet/aspnetcore#25288.

Version introduced

5.0 RC 1

Old behavior

The Exception Handler Middleware produces an HTTP 404 response if the configured exception handler can't be found.

New behavior

The Exception Handler Middleware throws the original exception if the configured exception handler can't be found.

Reason for change

The HTTP 404 error doesn't make it obvious that an exception occurred on the server. This change produces an HTTP 500 error to make it obvious that:

  • The problem isn't caused by a user error.
  • An exception was encountered on the server.

There are no API changes. All existing apps will continue to compile and run. The exception thrown is handled by the server. For example, the exception is converted to an HTTP 500 error response by Kestrel or HTTP.sys.

Category

ASP.NET Core

Affected APIs

None


MVC: ObjectModelValidator calls a new overload of ValidationVisitor.Validate

In ASP.NET Core 5.0, an overload of the ValidationVisitor.Validate was added. The new overload accepts the top-level model instance that contains properties:

  bool Validate(ModelMetadata metadata, string key, object model, bool alwaysValidateAtTopLevel);
+ bool Validate(ModelMetadata metadata, string key, object model, bool alwaysValidateAtTopLevel, object container);

ObjectModelValidator invokes this new overload of ValidationVisitor to perform validation. This new overload is pertinent if your validation library integrates with ASP.NET Core MVC's model validation system.

For discussion, see GitHub issue dotnet/aspnetcore#26020.

Version introduced

5.0

Old behavior

ObjectModelValidator invokes the following overload during model validation:

ValidationVisitor.Validate(ModelMetadata metadata, string key, object model, bool alwaysValidateAtTopLevel)

New behavior

ObjectModelValidator invokes the following overload during model validation:

ValidationVisitor.Validate(ModelMetadata metadata, string key, object model, bool alwaysValidateAtTopLevel, object container)

Reason for change

This change was introduced to support validators, such as CompareAttribute, that rely on inspection of other properties.

Validation frameworks that rely on ObjectModelValidator to invoke the existing overload of ValidationVisitor must override the new method when targeting .NET 5.0 or later:

public class MyCustomValidationVisitor : ValidationVisitor
{
+  public override bool Validate(ModelMetadata metadata, string key, object model, bool alwaysValidateAtTopLevel, object container)
+  {
+    ...
}

Category

ASP.NET Core

Affected APIs

ValidationVisitor.Validate


The HTTP cookie standard allows only specific characters in cookie names and values. To support disallowed characters, ASP.NET Core:

  • Encodes when creating a response cookie.
  • Decodes when reading a request cookie.

In ASP.NET Core 5.0, this encoding behavior changed in response to a security concern.

For discussion, see GitHub issue dotnet/aspnetcore#23578.

Version introduced

5.0 Preview 8

Old behavior

Response cookie names are encoded. Request cookie names are decoded.

New behavior

Encoding and decoding of cookie names was removed. For prior supported versions of ASP.NET Core, the team plans to mitigate the decoding issue in-place. Additionally, calling IResponseCookies.Append with an invalid cookie name throws an exception of type ArgumentException. Encoding and decoding of cookie values remains unchanged.

Reason for change

An issue was discovered in multiple web frameworks. The encoding and decoding could allow an attacker to bypass a security feature called cookie prefixes by spoofing reserved prefixes like __Host- with encoded values like __%48ost-. The attack requires a secondary exploit to inject the spoofed cookies, such as a cross-site scripting (XSS) vulnerability, in the website. These prefixes aren't used by default in ASP.NET Core or Microsoft.Owin libraries or templates.

If you're moving projects to ASP.NET Core 5.0 or later, ensure that their cookie names conform to the token specification requirements: ASCII characters excluding controls and separators "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT. The use of non-ASCII characters in cookie names or other HTTP headers may cause an exception from the server or be improperly round-tripped by the client.

Category

ASP.NET Core

Affected APIs


Security: IdentityModel NuGet package versions updated

The following packages were updated to version 6.6.0:

Version introduced

5.0 Preview 7

Old behavior

The package version used is 5.5.0.

New behavior

For details about changes between package versions, see the 6.6.0 release notes.

Reason for change

The packages were updated to take advantage of improvements in the underlying libraries.

The package updates don't introduce public API changes to ASP.NET Core. However, it's possible there are breaking changes in the packages themselves.

Category

ASP.NET Core

Affected APIs

None


SignalR: MessagePack Hub Protocol moved to MessagePack 2.x package

The ASP.NET Core SignalR MessagePack Hub Protocol uses the MessagePack NuGet package for MessagePack serialization. ASP.NET Core 5.0 upgrades the package from 1.x to the latest 2.x package version.

For discussion on this issue, see dotnet/aspnetcore#18692.

Version introduced

5.0 Preview 1

Old behavior

ASP.NET Core SignalR used the MessagePack 1.x package to serialize and deserialize MessagePack messages.

New behavior

ASP.NET Core SignalR uses the MessagePack 2.x package to serialize and deserialize MessagePack messages.

Reason for change

The latest improvements in the MessagePack 2.x package add useful functionality.

This breaking change applies when:

  • Setting or configuring values on MessagePackHubProtocolOptions.
  • Using the MessagePack APIs directly and using the ASP.NET Core SignalR MessagePack Hub Protocol in the same project. The newer version will be loaded instead of the previous version.

For migration guidance from the package authors, see Migrating from MessagePack v1.x to MessagePack v2.x. Some aspects of message serialization and deserialization are affected. Specifically, there are behavioral changes to how DateTime values are serialized.

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.SignalR.MessagePackHubProtocolOptions


SignalR: MessagePack Hub Protocol options type changed

The ASP.NET Core SignalR MessagePack Hub Protocol options type has changed from IList<MessagePack.IFormatterResolver> to the MessagePack library's MessagePackSerializerOptions type.

For discussion on this change, see dotnet/aspnetcore#20506.

Version introduced

5.0 Preview 4

Old behavior

You can add to the options as shown in the following example:

services.AddSignalR()
    .AddMessagePackProtocol(options =>
    {
        options.FormatterResolvers.Add(MessagePack.Resolvers.StandardResolver.Instance);
    });

And replace the options as follows:

services.AddSignalR()
    .AddMessagePackProtocol(options =>
    {
        options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
        {
            MessagePack.Resolvers.StandardResolver.Instance
        };
    });

New behavior

You can add to the options as shown in the following example:

services.AddSignalR()
    .AddMessagePackProtocol(options =>
    {
        options.SerializerOptions =
            options.SerializeOptions.WithResolver(MessagePack.Resolvers.StandardResolver.Instance);
    });

And replace the options as follows:

services.AddSignalR()
    .AddMessagePackProtocol(options =>
    {
        options.SerializerOptions = MessagePackSerializerOptions
                .Standard
                .WithResolver(MessagePack.Resolvers.StandardResolver.Instance)
                .WithSecurity(MessagePackSecurity.UntrustedData);
    });

Reason for change

This change is part of moving to MessagePack v2.x, which was announced in aspnet/Announcements#404. The v2.x library has added an options API that's easier to use and provides more features than the list of MessagePack.IFormatterResolver that was exposed before.

This breaking change affects anyone who is configuring values on MessagePackHubProtocolOptions. If you're using the ASP.NET Core SignalR MessagePack Hub Protocol and modifying the options, update your usage to use the new options API as shown above.

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.SignalR.MessagePackHubProtocolOptions


SignalR: UseSignalR and UseConnections methods removed

In ASP.NET Core 3.0, SignalR adopted endpoint routing. As part of that change, the UseSignalR, UseConnections, and some related methods were marked as obsolete. In ASP.NET Core 5.0, those obsolete methods were removed. For the full list of methods, see Affected APIs.

For discussion on this issue, see dotnet/aspnetcore#20082.

Version introduced

5.0 Preview 3

Old behavior

SignalR hubs and connection handlers could be registered in the middleware pipeline using the UseSignalR or UseConnections methods.

New behavior

SignalR hubs and connection handlers should be registered within UseEndpoints using the MapHub and MapConnectionHandler extension methods on IEndpointRouteBuilder.

Reason for change

The old methods had custom routing logic that didn't interact with other routing components in ASP.NET Core. In ASP.NET Core 3.0, a new general-purpose routing system, called endpoint routing, was introduced. Endpoint routing enabled SignalR to interact with other routing components. Switching to this model allows users to realize the full benefits of endpoint routing. Consequently, the old methods have been removed.

Remove code that calls UseSignalR or UseConnections from your project's Startup.Configure method. Replace it with calls to MapHub or MapConnectionHandler, respectively, within the body of a call to UseEndpoints. For example:

Old code:

app.UseSignalR(routes =>
{
    routes.MapHub<SomeHub>("/path");
});

New code:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHub<SomeHub>("/path");
});

In general, your previous MapHub and MapConnectionHandler calls can be transferred directly from the body of UseSignalR and UseConnections to UseEndpoints with little-to-no change needed.

Category

ASP.NET Core

Affected APIs


System.Security.Cryptography APIs not supported on Blazor WebAssembly

System.Security.Cryptography APIs throw a PlatformNotSupportedException at run time when run on a browser.

Change description

In previous .NET versions, most of the System.Security.Cryptography APIs aren't available to Blazor WebAssembly apps. Starting in .NET 5.0, Blazor WebAssembly apps target the full .NET 5 API surface area, however, not all .NET 5 APIs are supported due to browser sandbox constraints. In .NET 5.0 and later versions, the unsupported System.Security.Cryptography APIs throw a PlatformNotSupportedException when running on WebAssembly.

Tip

The Platform compatibility analyzer will flag any calls to the affected APIs when you build a project that supports the browser platform. This analyzer runs by default in .NET 5.0 and later apps.

Reason for change

Microsoft is unable to ship OpenSSL as a dependency in the Blazor WebAssembly configuration. We attempted to work around this by trying to integrate with the browser's SubtleCrypto API. Unfortunately, it required significant API changes that made it too hard to integrate.

Version introduced

5.0 RC1

There are no good workarounds to suggest at this time.

Category

  • ASP.NET Core
  • Cryptography

Affected APIs

All System.Security.Cryptography APIs except the following:

  • System.Security.Cryptography.RandomNumberGenerator
  • System.Security.Cryptography.IncrementalHash
  • System.Security.Cryptography.SHA1
  • System.Security.Cryptography.SHA256
  • System.Security.Cryptography.SHA384
  • System.Security.Cryptography.SHA512
  • System.Security.Cryptography.SHA1Managed
  • System.Security.Cryptography.SHA256Managed
  • System.Security.Cryptography.SHA384Managed
  • System.Security.Cryptography.SHA512Managed

Static files: CSV content type changed to standards-compliant

In ASP.NET Core 5.0, the default Content-Type response header value that the Static File Middleware uses for .csv files has changed to the standards-compliant value text/csv.

For discussion on this issue, see dotnet/aspnetcore#17385.

Version introduced

5.0 Preview 1

Old behavior

The Content-Type header value application/octet-stream was used.

New behavior

The Content-Type header value text/csv is used.

Reason for change

Compliance with the RFC 7111 standard.

If this change impacts your app, you can customize the file extension-to-MIME type mapping. To revert to the application/octet-stream MIME type, modify the UseStaticFiles method call in Startup.Configure. For example:

var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".csv"] = MediaTypeNames.Application.Octet;

app.UseStaticFiles(new StaticFileOptions
{
    ContentTypeProvider = provider
});

For more information on customizing the mapping, see FileExtensionContentTypeProvider.

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider


ASP.NET Core 3.1

HTTP: Browser SameSite changes impact authentication

Some browsers, such as Chrome and Firefox, made breaking changes to their implementations of SameSite for cookies. The changes impact remote authentication scenarios, such as OpenID Connect and WS-Federation, which must opt out by sending SameSite=None. However, SameSite=None breaks on iOS 12 and some older versions of other browsers. The app needs to sniff these versions and omit SameSite.

For discussion on this issue, see dotnet/aspnetcore#14996.

Version introduced

3.1 Preview 1

Old behavior

SameSite is a 2016 draft standard extension to HTTP cookies. It's intended to mitigate Cross-Site Request Forgery (CSRF). This was originally designed as a feature the servers would opt into by adding the new parameters. ASP.NET Core 2.0 added initial support for SameSite.

New behavior

Google proposed a new draft standard that isn't backwards compatible. The standard changes the default mode to Lax and adds a new entry None to opt out. Lax suffices for most app cookies; however, it breaks cross-site scenarios like OpenID Connect and WS-Federation login. Most OAuth logins aren't affected because of differences in how the request flows. The new None parameter causes compatibility problems with clients that implemented the prior draft standard (for example, iOS 12). Chrome 80 will include the changes. See SameSite Updates for the Chrome product launch timeline.

ASP.NET Core 3.1 has been updated to implement the new SameSite behavior. The update redefines the behavior of SameSiteMode.None to emit SameSite=None and adds a new value SameSiteMode.Unspecified to omit the SameSite attribute. All cookie APIs now default to Unspecified, though some components that use cookies set values more specific to their scenarios such as the OpenID Connect correlation and nonce cookies.

For other recent changes in this area, see HTTP: Some cookie SameSite defaults changed to None. In ASP.NET Core 3.0, most defaults were changed from SameSiteMode.Lax to SameSiteMode.None (but still using the prior standard).

Reason for change

Browser and specification changes as outlined in the preceding text.

Apps that interact with remote sites, such as through third-party login, need to:

  • Test those scenarios on multiple browsers.
  • Apply the cookie policy browser sniffing mitigation discussed in Support older browsers.

For testing and browser sniffing instructions, see the following section.

Determine if you're affected

Test your web app using a client version that can opt into the new behavior. Chrome, Firefox, and Microsoft Edge Chromium all have new opt-in feature flags that can be used for testing. Verify that your app is compatible with older client versions after you've applied the patches, especially Safari. For more information, see Support older browsers.

Chrome

Chrome 78 and later yield misleading test results. Those versions have a temporary mitigation in place and allow cookies less than two minutes old. With the appropriate test flags enabled, Chrome 76 and 77 yield more accurate results. To test the new behavior, toggle chrome://flags/#same-site-by-default-cookies to enabled. Chrome 75 and earlier are reported to fail with the new None setting. For more information, see Support older browsers.

Google doesn't make older Chrome versions available. You can, however, download older versions of Chromium, which will suffice for testing. Follow the instructions at Download Chromium.

Safari

Safari 12 strictly implemented the prior draft and fails if it sees the new None value in cookies. This must be avoided via the browser sniffing code shown in Support older browsers. Ensure you test Safari 12 and 13 as well as WebKit-based, OS-style logins using Microsoft Authentication Library (MSAL), Active Directory Authentication Library (ADAL), or whichever library you're using. The problem is dependent on the underlying OS version. OSX Mojave 10.14 and iOS 12 are known to have compatibility problems with the new behavior. Upgrading to OSX Catalina 10.15 or iOS 13 fixes the problem. Safari doesn't currently have an opt-in flag for testing the new specification behavior.

Firefox

Firefox support for the new standard can be tested on version 68 and later by opting in on the about:config page with the feature flag network.cookie.sameSite.laxByDefault. No compatibility issues have been reported on older versions of Firefox.

Microsoft Edge

While Microsoft Edge supports the old SameSite standard, as of version 44 it didn't have any compatibility problems with the new standard.

Microsoft Edge Chromium

The feature flag is edge://flags/#same-site-by-default-cookies. No compatibility issues were observed when testing with Microsoft Edge Chromium 78.

Electron

Versions of Electron include older versions of Chromium. For example, the version of Electron used by Microsoft Teams is Chromium 66, which exhibits the older behavior. Perform your own compatibility testing with the version of Electron your product uses. For more information, see Support older browsers.

Support older browsers

The 2016 SameSite standard mandated that unknown values be treated as SameSite=Strict values. Consequently, any older browsers that support the original standard may break when they see a SameSite property with a value of None. Web apps must implement browser sniffing if they intend to support these old browsers. ASP.NET Core doesn't implement browser sniffing for you because User-Agent request header values are highly unstable and change on a weekly basis. Instead, an extension point in the cookie policy allows you to add User-Agent-specific logic.

In Startup.cs, add the following code:

private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
    if (options.SameSite == SameSiteMode.None)
    {
        var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
        // TODO: Use your User Agent library of choice here.
        if (/* UserAgent doesn't support new behavior */)
        {
            options.SameSite = SameSiteMode.Unspecified;
        }
    }
}

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
        options.OnAppendCookie = cookieContext =>
            CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
        options.OnDeleteCookie = cookieContext =>
            CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
    });
}

public void Configure(IApplicationBuilder app)
{
    // Before UseAuthentication or anything else that writes cookies.
    app.UseCookiePolicy();

    app.UseAuthentication();
    // code omitted for brevity
}
Opt-out switches

The Microsoft.AspNetCore.SuppressSameSiteNone compatibility switch enables you to temporarily opt out of the new ASP.NET Core cookie behavior. Add the following JSON to a runtimeconfig.template.json file in your project:

{
  "configProperties": {
    "Microsoft.AspNetCore.SuppressSameSiteNone": "true"
  }
}
Other Versions

Related SameSite patches are forthcoming for:

  • ASP.NET Core 2.1, 2.2, and 3.0
  • Microsoft.Owin 4.1
  • System.Web (for .NET Framework 4.7.2 and later)

Category

ASP.NET

Affected APIs


ASP.NET Core 3.0

Obsolete Antiforgery, CORS, Diagnostics, MVC, and Routing APIs removed

Obsolete members and compatibility switches in ASP.NET Core 2.2 were removed.

Version introduced

3.0

Reason for change

Improvement of API surface over time.

While targeting .NET Core 2.2, follow the guidance in the obsolete build messages to adopt new APIs instead.

Category

ASP.NET Core

Affected APIs

The following types and members were marked as obsolete for ASP.NET Core 2.1 and 2.2:

Types

  • Microsoft.AspNetCore.Diagnostics.Views.WelcomePage
  • Microsoft.AspNetCore.DiagnosticsViewPage.Views.AttributeValue
  • Microsoft.AspNetCore.DiagnosticsViewPage.Views.BaseView
  • Microsoft.AspNetCore.DiagnosticsViewPage.Views.HelperResult
  • Microsoft.AspNetCore.Mvc.Formatters.Xml.ProblemDetails21Wrapper
  • Microsoft.AspNetCore.Mvc.Formatters.Xml.ValidationProblemDetails21Wrapper
  • Microsoft.AspNetCore.Mvc.Razor.Compilation.ViewsFeatureProvider
  • Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageArgumentBinder
  • Microsoft.AspNetCore.Routing.IRouteValuesAddressMetadata
  • Microsoft.AspNetCore.Routing.RouteValuesAddressMetadata

Constructors

  • Microsoft.AspNetCore.Cors.Infrastructure.CorsService(IOptions{CorsOptions})
  • Microsoft.AspNetCore.Routing.Tree.TreeRouteBuilder(ILoggerFactory,UrlEncoder,ObjectPool{UriBuildingContext},IInlineConstraintResolver)
  • Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterCanWriteContext
  • Microsoft.AspNetCore.Mvc.ApiExplorer.DefaultApiDescriptionProvider(IOptions{MvcOptions},IInlineConstraintResolver,IModelMetadataProvider)
  • Microsoft.AspNetCore.Mvc.ApiExplorer.DefaultApiDescriptionProvider(IOptions{MvcOptions},IInlineConstraintResolver,IModelMetadataProvider,IActionResultTypeMapper)
  • Microsoft.AspNetCore.Mvc.Formatters.FormatFilter(IOptions{MvcOptions})
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ArrayModelBinder`1(IModelBinder)
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ByteArrayModelBinder
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.CollectionModelBinder`1(IModelBinder)
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder(IDictionary`2)
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.DictionaryModelBinder`2(IModelBinder,IModelBinder)
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.DoubleModelBinder(System.Globalization.NumberStyles)
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FloatModelBinder(System.Globalization.NumberStyles)
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormCollectionModelBinder
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormFileModelBinder
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.HeaderModelBinder
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.KeyValuePairModelBinder`2(IModelBinder,IModelBinder)
  • Microsoft.AspNetCore.Mvc.ModelBinding.Binders.SimpleTypeModelBinder(System.Type)
  • Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes(IEnumerable{System.Object})
  • Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes(IEnumerable{System.Object},IEnumerable{System.Object})
  • Microsoft.AspNetCore.Mvc.ModelBinding.ModelBinderFactory(IModelMetadataProvider,IOptions{MvcOptions})
  • Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder(IModelMetadataProvider,IModelBinderFactory,IObjectModelValidator)
  • Microsoft.AspNetCore.Mvc.Routing.KnownRouteValueConstraint()
  • Microsoft.AspNetCore.Mvc.Formatters.XmlDataContractSerializerInputFormatter
  • Microsoft.AspNetCore.Mvc.Formatters.XmlDataContractSerializerInputFormatter(System.Boolean)
  • Microsoft.AspNetCore.Mvc.Formatters.XmlDataContractSerializerInputFormatter(MvcOptions)
  • Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerInputFormatter
  • Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerInputFormatter(System.Boolean)
  • Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerInputFormatter(MvcOptions)
  • Microsoft.AspNetCore.Mvc.TagHelpers.ImageTagHelper(IHostingEnvironment,IMemoryCache,HtmlEncoder,IUrlHelperFactory)
  • Microsoft.AspNetCore.Mvc.TagHelpers.LinkTagHelper(IHostingEnvironment,IMemoryCache,HtmlEncoder,JavaScriptEncoder,IUrlHelperFactory)
  • Microsoft.AspNetCore.Mvc.TagHelpers.ScriptTagHelper(IHostingEnvironment,IMemoryCache,HtmlEncoder,JavaScriptEncoder,IUrlHelperFactory)
  • Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAdapter(RazorPageBase)

Properties

  • Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.CookieDomain
  • Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.CookieName
  • Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.CookiePath
  • Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions.RequireSsl
  • Microsoft.AspNetCore.Mvc.ApiBehaviorOptions.AllowInferringBindingSourceForCollectionTypesAsFromQuery
  • Microsoft.AspNetCore.Mvc.ApiBehaviorOptions.SuppressUseValidationProblemDetailsForInvalidModelStateResponses
  • Microsoft.AspNetCore.Mvc.CookieTempDataProviderOptions.CookieName
  • Microsoft.AspNetCore.Mvc.CookieTempDataProviderOptions.Domain
  • Microsoft.AspNetCore.Mvc.CookieTempDataProviderOptions.Path
  • Microsoft.AspNetCore.Mvc.DataAnnotations.MvcDataAnnotationsLocalizationOptions.AllowDataAnnotationsLocalizationForEnumDisplayAttributes
  • Microsoft.AspNetCore.Mvc.Formatters.Xml.MvcXmlOptions.AllowRfc7807CompliantProblemDetailsFormat
  • Microsoft.AspNetCore.Mvc.MvcOptions.AllowBindingHeaderValuesToNonStringModelTypes
  • Microsoft.AspNetCore.Mvc.MvcOptions.AllowCombiningAuthorizeFilters
  • Microsoft.AspNetCore.Mvc.MvcOptions.AllowShortCircuitingValidationWhenNoValidatorsArePresent
  • Microsoft.AspNetCore.Mvc.MvcOptions.AllowValidatingTopLevelNodes
  • Microsoft.AspNetCore.Mvc.MvcOptions.InputFormatterExceptionPolicy
  • Microsoft.AspNetCore.Mvc.MvcOptions.SuppressBindingUndefinedValueToEnumType
  • Microsoft.AspNetCore.Mvc.MvcViewOptions.AllowRenderingMaxLengthAttribute
  • Microsoft.AspNetCore.Mvc.MvcViewOptions.SuppressTempDataAttributePrefix
  • Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptions.AllowAreas
  • Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptions.AllowDefaultHandlingForOptionsRequests
  • Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptions.AllowMappingHeadRequestsToGetHandler

Methods


Authentication: Google+ deprecated and replaced

Google is starting to shut down Google+ Sign-in for apps as early as January 28, 2019.

Change description

ASP.NET 4.x and ASP.NET Core have been using the Google+ Sign-in APIs to authenticate Google account users in web apps. The affected NuGet packages are Microsoft.AspNetCore.Authentication.Google for ASP.NET Core and Microsoft.Owin.Security.Google for Microsoft.Owin with ASP.NET Web Forms and MVC.

Google's replacement APIs use a different data source and format. The mitigations and solutions provided below account for the structural changes. Apps should verify the data itself still satisfies their requirements. For example, names, email addresses, profile links, and profile photos may provide subtly different values than before.

Version introduced

All versions. This change is external to ASP.NET Core.

Owin with ASP.NET Web Forms and MVC

For Microsoft.Owin 3.1.0 and later, a temporary mitigation is outlined here. Apps should complete testing with the mitigation to check for changes in the data format. There are plans to release Microsoft.Owin 4.0.1 with a fix. Apps using any prior version should update to version 4.0.1.

ASP.NET Core 1.x

The mitigation in Owin with ASP.NET Web Forms and MVC can be adapted to ASP.NET Core 1.x. NuGet package patches aren't planned because 1.x has reached end of life status.

ASP.NET Core 2.x

For Microsoft.AspNetCore.Authentication.Google version 2.x, replace your existing call to AddGoogle in Startup.ConfigureServices with the following code:

.AddGoogle(o =>
{
    o.ClientId = Configuration["Authentication:Google:ClientId"];
    o.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
    o.UserInformationEndpoint = "https://www.googleapis.com/oauth2/v2/userinfo";
    o.ClaimActions.Clear();
    o.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
    o.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
    o.ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name");
    o.ClaimActions.MapJsonKey(ClaimTypes.Surname, "family_name");
    o.ClaimActions.MapJsonKey("urn:google:profile", "link");
    o.ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
});

The February 2.1 and 2.2 patches incorporated the preceding reconfiguration as the new default. No patch is planned for ASP.NET Core 2.0 since it has reached end of life.

ASP.NET Core 3.0

The mitigation given for ASP.NET Core 2.x can also be used for ASP.NET Core 3.0. In future 3.0 previews, the Microsoft.AspNetCore.Authentication.Google package may be removed. Users would be directed to Microsoft.AspNetCore.Authentication.OpenIdConnect instead. The following code shows how to replace AddGoogle with AddOpenIdConnect in Startup.ConfigureServices. This replacement can be used with ASP.NET Core 2.0 and later and can be adapted for ASP.NET Core 1.x as needed.

.AddOpenIdConnect("Google", o =>
{
    o.ClientId = Configuration["Authentication:Google:ClientId"];
    o.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
    o.Authority = "https://accounts.google.com";
    o.ResponseType = OpenIdConnectResponseType.Code;
    o.CallbackPath = "/signin-google"; // Or register the default "/sigin-oidc"
    o.Scope.Add("email");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.Authentication.Google


Authentication: HttpContext.Authentication property removed

The deprecated Authentication property on HttpContext has been removed.

Change description

As part of dotnet/aspnetcore#6504, the deprecated Authentication property on HttpContext has been removed. The Authentication property has been deprecated since 2.0. A migration guide was published to migrate code using this deprecated property to the new replacement APIs. The remaining unused classes / APIs related to the old ASP.NET Core 1.x authentication stack were removed in commit dotnet/aspnetcore@d7a7c65.

For discussion, see dotnet/aspnetcore#6533.

Version introduced

3.0

Reason for change

ASP.NET Core 1.0 APIs have been replaced by extension methods in Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.

See the migration guide.

Category

ASP.NET Core

Affected APIs


Authentication: Newtonsoft.Json types replaced

In ASP.NET Core 3.0, Newtonsoft.Json types used in Authentication APIs have been replaced with System.Text.Json types. Except for the following cases, basic usage of the Authentication packages remains unaffected:

  • Classes derived from the OAuth providers, such as those from aspnet-contrib.
  • Advanced claim manipulation implementations.

For more information, see dotnet/aspnetcore#7105. For discussion, see dotnet/aspnetcore#7289.

Version introduced

3.0

For derived OAuth implementations, the most common change is to replace JObject.Parse with JsonDocument.Parse in the CreateTicketAsync override as shown here. JsonDocument implements IDisposable.

The following list outlines known changes:

Category

ASP.NET Core

Affected APIs


Authentication: OAuthHandler ExchangeCodeAsync signature changed

In ASP.NET Core 3.0, the signature of OAuthHandler.ExchangeCodeAsync was changed from:

protected virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Authentication.OAuth.OAuthTokenResponse> ExchangeCodeAsync(string code, string redirectUri) { throw null; }

To:

protected virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Authentication.OAuth.OAuthTokenResponse> ExchangeCodeAsync(Microsoft.AspNetCore.Authentication.OAuth.OAuthCodeExchangeContext context) { throw null; }

Version introduced

3.0

Old behavior

The code and redirectUri strings were passed as separate arguments.

New behavior

Code and RedirectUri are properties on OAuthCodeExchangeContext that can be set via the OAuthCodeExchangeContext constructor. The new OAuthCodeExchangeContext type is the only argument passed to OAuthHandler.ExchangeCodeAsync.

Reason for change

This change allows additional parameters to be provided in a non-breaking manner. There's no need to create new ExchangeCodeAsync overloads.

Construct an OAuthCodeExchangeContext with the appropriate code and redirectUri values. An AuthenticationProperties instance must be provided. This single OAuthCodeExchangeContext instance can be passed to OAuthHandler.ExchangeCodeAsync instead of multiple arguments.

Category

ASP.NET Core

Affected APIs

OAuthHandler<TOptions>.ExchangeCodeAsync(String, String)


Authorization: AddAuthorization overload moved to different assembly

The core AddAuthorization methods that used to reside in Microsoft.AspNetCore.Authorization were renamed to AddAuthorizationCore. The old AddAuthorization methods still exist, but are in the Microsoft.AspNetCore.Authorization.Policy assembly instead. Apps using both methods should see no impact. Note that Microsoft.AspNetCore.Authorization.Policy now ships in the shared framework rather than a standalone package as discussed in Shared framework: Assemblies removed from Microsoft.AspNetCore.App.

Version introduced

3.0

Old behavior

AddAuthorization methods existed in Microsoft.AspNetCore.Authorization.

New behavior

AddAuthorization methods exist in Microsoft.AspNetCore.Authorization.Policy. AddAuthorizationCore is the new name for the old methods.

Reason for change

AddAuthorization is a better method name for adding all common services needed for authorization.

Either add a reference to Microsoft.AspNetCore.Authorization.Policy or use AddAuthorizationCore instead.

Category

ASP.NET Core

Affected APIs

Microsoft.Extensions.DependencyInjection.AuthorizationServiceCollectionExtensions.AddAuthorization(IServiceCollection, Action<AuthorizationOptions>)


Authorization: IAllowAnonymous removed from AuthorizationFilterContext.Filters

As of ASP.NET Core 3.0, MVC doesn't add AllowAnonymousFilters for [AllowAnonymous] attributes that were discovered on controllers and action methods. This change is addressed locally for derivatives of AuthorizeAttribute, but it's a breaking change for IAsyncAuthorizationFilter and IAuthorizationFilter implementations. Such implementations wrapped in a [TypeFilter] attribute are a popular and supported way to achieve strongly-typed, attribute-based authorization when both configuration and dependency injection are required.

Version introduced

3.0

Old behavior

IAllowAnonymous appeared in the AuthorizationFilterContext.Filters collection. Testing for the interface's presence was a valid approach to override or disable the filter on individual controller methods.

New behavior

IAllowAnonymous no longer appears in the AuthorizationFilterContext.Filters collection. IAsyncAuthorizationFilter implementations that are dependent on the old behavior typically cause intermittent HTTP 401 Unauthorized or HTTP 403 Forbidden responses.

Reason for change

A new endpoint routing strategy was introduced in ASP.NET Core 3.0.

Search the endpoint metadata for IAllowAnonymous. For example:

var endpoint = context.HttpContext.GetEndpoint();
if (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null)
{
}

An example of this technique is seen in this HasAllowAnonymous method.

Category

ASP.NET Core

Affected APIs

None


Authorization: IAuthorizationPolicyProvider implementations require new method

In ASP.NET Core 3.0, a new GetFallbackPolicyAsync method was added to IAuthorizationPolicyProvider. This fallback policy is used by the authorization middleware when no policy is specified.

For more information, see dotnet/aspnetcore#9759.

Version introduced

3.0

Old behavior

Implementations of IAuthorizationPolicyProvider didn't require a GetFallbackPolicyAsync method.

New behavior

Implementations of IAuthorizationPolicyProvider require a GetFallbackPolicyAsync method.

Reason for change

A new method was needed for the new AuthorizationMiddleware to use when no policy is specified.

Add the GetFallbackPolicyAsync method to your implementations of IAuthorizationPolicyProvider.

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.Authorization.IAuthorizationPolicyProvider


Caching: CompactOnMemoryPressure property removed

The ASP.NET Core 3.0 release removed the obsolete MemoryCacheOptions APIs.

Change description

This change is a follow-up to aspnet/Caching#221. For discussion, see dotnet/extensions#1062.

Version introduced

3.0

Old behavior

MemoryCacheOptions.CompactOnMemoryPressure property was available.

New behavior

The MemoryCacheOptions.CompactOnMemoryPressure property has been removed.

Reason for change

Automatically compacting the cache caused problems. To avoid unexpected behavior, the cache should only be compacted when needed.

To compact the cache, downcast to MemoryCache and call Compact when needed.

Category

ASP.NET Core

Affected APIs

MemoryCacheOptions.CompactOnMemoryPressure


Caching: Microsoft.Extensions.Caching.SqlServer uses new SqlClient package

The Microsoft.Extensions.Caching.SqlServer package will use the new Microsoft.Data.SqlClient package instead of System.Data.SqlClient package. This change could cause slight behavioral breaking changes. For more information, see Introducing the new Microsoft.Data.SqlClient.

Version introduced

3.0

Old behavior

The Microsoft.Extensions.Caching.SqlServer package used the System.Data.SqlClient package.

New behavior

Microsoft.Extensions.Caching.SqlServer is now using the Microsoft.Data.SqlClient package.

Reason for change

Microsoft.Data.SqlClient is a new package that is built off of System.Data.SqlClient. It's where all new feature work will be done from now on.

Customers shouldn't need to worry about this breaking change unless they were using types returned by the Microsoft.Extensions.Caching.SqlServer package and casting them to System.Data.SqlClient types. For example, if someone was casting a DbConnection to the old SqlConnection type, they would need to change the cast to the new Microsoft.Data.SqlClient.SqlConnection type.

Category

ASP.NET Core

Affected APIs

None


Caching: ResponseCaching "pubternal" types changed to internal

In ASP.NET Core 3.0, "pubternal" types in ResponseCaching have been changed to internal.

In addition, default implementations of IResponseCachingPolicyProvider and IResponseCachingKeyProvider are no longer added to services as part of the AddResponseCaching method.

Change description

In ASP.NET Core, "pubternal" types are declared as public but reside in a namespace suffixed with .Internal. While these types are public, they have no support policy and are subject to breaking changes. Unfortunately, accidental use of these types has been common, resulting in breaking changes to these projects and limiting the ability to maintain the framework.

Version introduced

3.0

Old behavior

These types were publicly visible, but unsupported.

New behavior

These types are now internal.

Reason for change

The internal scope better reflects the unsupported policy.

Copy types that are used by your app or library.

Category

ASP.NET Core

Affected APIs


Data Protection: DataProtection.AzureStorage uses new Azure Storage APIs

Microsoft.AspNetCore.DataProtection.AzureStorage depends on the Azure Storage libraries. These libraries renamed their assemblies, packages, and namespaces. Starting in ASP.NET Core 3.0, Microsoft.AspNetCore.DataProtection.AzureStorage uses the new Microsoft.Azure.Storage.-prefixed APIs and packages.

For questions about the Azure Storage APIs, use https://github.com/Azure/azure-storage-net. For discussion on this issue, see dotnet/aspnetcore#8472.

Version introduced

3.0

Old behavior

The package referenced the WindowsAzure.Storage NuGet package.

New behavior

The package references the Microsoft.Azure.Storage.Blob NuGet package.

Reason for change

This change allows Microsoft.AspNetCore.DataProtection.AzureStorage to migrate to the recommended Azure Storage packages.

If you still need to use the older Azure Storage APIs with ASP.NET Core 3.0, add a direct dependency to the WindowsAzure.Storage package. This package can be installed alongside the new Microsoft.Azure.Storage APIs.

In many cases, the upgrade only involves changing the using statements to use the new namespaces:

- using Microsoft.WindowsAzure.Storage;
- using Microsoft.WindowsAzure.Storage.Blob;
+ using Microsoft.Azure.Storage;
+ using Microsoft.Azure.Storage.Blob;

Category

ASP.NET Core

Affected APIs

None


Hosting: AspNetCoreModule V1 removed from Windows Hosting Bundle

Starting with ASP.NET Core 3.0, the Windows Hosting Bundle won't contain AspNetCoreModule (ANCM) V1.

ANCM V2 is backwards compatible with ANCM OutOfProcess and is recommended for use with ASP.NET Core 3.0 apps.

For discussion, see dotnet/aspnetcore#7095.

Version introduced

3.0

Old behavior

ANCM V1 is included in the Windows Hosting Bundle.

New behavior

ANCM V1 isn't included in the Windows Hosting Bundle.

Reason for change

ANCM V2 is backwards compatible with ANCM OutOfProcess and is recommended for use with ASP.NET Core 3.0 apps.

Use ANCM V2 with ASP.NET Core 3.0 apps.

If ANCM V1 is required, it can be installed using the ASP.NET Core 2.1 or 2.2 Windows Hosting Bundle.

This change will break ASP.NET Core 3.0 apps that:

  • Explicitly opted into using ANCM V1 with <AspNetCoreModuleName>AspNetCoreModule</AspNetCoreModuleName>.
  • Have a custom web.config file with <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />.

Category

ASP.NET Core

Affected APIs

None


Hosting: Generic host restricts Startup constructor injection

The only types the generic host supports for Startup class constructor injection are IHostEnvironment, IWebHostEnvironment, and IConfiguration. Apps using WebHost are unaffected.

Change description

Prior to ASP.NET Core 3.0, constructor injection could be used for arbitrary types in the Startup class's constructor. In ASP.NET Core 3.0, the web stack was replatformed onto the generic host library. You can see the change in the Program.cs file of the templates:

ASP.NET Core 2.x:

https://github.com/dotnet/aspnetcore/blob/5cb615fcbe8559e49042e93394008077e30454c0/src/Templating/src/Microsoft.DotNet.Web.ProjectTemplates/content/EmptyWeb-CSharp/Program.cs#L20-L22

ASP.NET Core 3.0:

https://github.com/dotnet/aspnetcore/blob/b1ca2c1155da3920f0df5108b9fedbe82efaa11c/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/Program.cs#L19-L24

Host uses one dependency injection (DI) container to build the app. WebHost uses two containers: one for the host and one for the app. As a result, the Startup constructor no longer supports custom service injection. Only IHostEnvironment, IWebHostEnvironment, and IConfiguration can be injected. This change prevents DI issues such as the duplicate creation of a singleton service.

Version introduced

3.0

Reason for change

This change is a consequence of replatforming the web stack onto the generic host library.

Inject services into the Startup.Configure method signature. For example:

public void Configure(IApplicationBuilder app, IOptions<MyOptions> options)

Category

ASP.NET Core

Affected APIs

None


Hosting: HTTPS redirection enabled for IIS out-of-process apps

Version 13.0.19218.0 of the ASP.NET Core Module (ANCM) for hosting via IIS out-of-process enables an existing HTTPS redirection feature for ASP.NET Core 3.0 and 2.2 apps.

For discussion, see dotnet/AspNetCore#15243.

Version introduced

3.0

Old behavior

The ASP.NET Core 2.1 project template first introduced support for HTTPS middleware methods like UseHttpsRedirection and UseHsts. Enabling HTTPS redirection required the addition of configuration, since apps in development don't use the default port of 443. HTTP Strict Transport Security (HSTS) is active only if the request is already using HTTPS. Localhost is skipped by default.

New behavior

In ASP.NET Core 3.0, the IIS HTTPS scenario was enhanced. With the enhancement, an app could discover the server's HTTPS ports and make UseHttpsRedirection work by default. The in-process component accomplished port discovery with the IServerAddresses feature, which only affects ASP.NET Core 3.0 apps because the in-process library is versioned with the framework. The out-of-process component changed to automatically add the ASPNETCORE_HTTPS_PORT environment variable. This change affected both ASP.NET Core 2.2 and 3.0 apps because the out-of-process component is shared globally. ASP.NET Core 2.1 apps aren't affected because they use a prior version of ANCM by default.

The preceding behavior was modified in ASP.NET Core 3.0.1 and 3.1.0 Preview 3 to reverse the behavior changes in ASP.NET Core 2.x. These changes only affect IIS out-of-process apps.

As detailed above, installing ASP.NET Core 3.0.0 had the side effect of also activating the UseHttpsRedirection middleware in ASP.NET Core 2.x apps. A change was made to ANCM in ASP.NET Core 3.0.1 and 3.1.0 Preview 3 such that installing them no longer has this effect on ASP.NET Core 2.x apps. The ASPNETCORE_HTTPS_PORT environment variable that ANCM populated in ASP.NET Core 3.0.0 was changed to ASPNETCORE_ANCM_HTTPS_PORT in ASP.NET Core 3.0.1 and 3.1.0 Preview 3. UseHttpsRedirection was also updated in these releases to understand both the new and old variables. ASP.NET Core 2.x won't be updated. As a result, it reverts to the previous behavior of being disabled by default.

Reason for change

Improved ASP.NET Core 3.0 functionality.

No action is required if you want all clients to use HTTPS. To allow some clients to use HTTP, take one of the following steps:

  • Remove the calls to UseHttpsRedirection and UseHsts from your project's Startup.Configure method, and redeploy the app.

  • In your web.config file, set the ASPNETCORE_HTTPS_PORT environment variable to an empty string. This change can occur directly on the server without redeploying the app. For example:

    <aspNetCore processPath="dotnet" arguments=".\WebApplication3.dll" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" >
        <environmentVariables>
        <environmentVariable name="ASPNETCORE_HTTPS_PORT" value="" />
        </environmentVariables>
    </aspNetCore>
    

UseHttpsRedirection can still be:

  • Activated manually in ASP.NET Core 2.x by setting the ASPNETCORE_HTTPS_PORT environment variable to the appropriate port number (443 in most production scenarios).
  • Deactivated in ASP.NET Core 3.x by defining ASPNETCORE_ANCM_HTTPS_PORT with an empty string value. This value is set in the same fashion as the preceding ASPNETCORE_HTTPS_PORT example.

Machines running ASP.NET Core 3.0.0 apps should install the ASP.NET Core 3.0.1 runtime before installing the ASP.NET Core 3.1.0 Preview 3 ANCM. Doing so ensures that UseHttpsRedirection continues to operate as expected for the ASP.NET Core 3.0 apps.

In Azure App Service, ANCM deploys on a separate schedule from the runtime because of its global nature. ANCM was deployed to Azure with these changes after ASP.NET Core 3.0.1 and 3.1.0 were deployed.

Category

ASP.NET Core

Affected APIs

HttpsPolicyBuilderExtensions.UseHttpsRedirection(IApplicationBuilder)


Hosting: IHostingEnvironment and IApplicationLifetime types marked obsolete and replaced

New types have been introduced to replace existing IHostingEnvironment and IApplicationLifetime types.

Version introduced

3.0

Old behavior

There were two different IHostingEnvironment and IApplicationLifetime types from Microsoft.Extensions.Hosting and Microsoft.AspNetCore.Hosting.

New behavior

The old types have been marked as obsolete and replaced with new types.

Reason for change

When Microsoft.Extensions.Hosting was introduced in ASP.NET Core 2.1, some types like IHostingEnvironment and IApplicationLifetime were copied from Microsoft.AspNetCore.Hosting. Some ASP.NET Core 3.0 changes cause apps to include both the Microsoft.Extensions.Hosting and Microsoft.AspNetCore.Hosting namespaces. Any use of those duplicate types causes an "ambiguous reference" compiler error when both namespaces are referenced.

Replaced any usages of the old types with the newly introduced types as below:

Obsolete types (warning):

New types:

The new IHostEnvironment IsDevelopment and IsProduction extension methods are in the Microsoft.Extensions.Hosting namespace. That namespace may need to be added to your project.

Category

ASP.NET Core

Affected APIs


Hosting: ObjectPoolProvider removed from WebHostBuilder dependencies

As part of making ASP.NET Core more pay for play, the ObjectPoolProvider was removed from the main set of dependencies. Specific components relying on ObjectPoolProvider now add it themselves.

For discussion, see dotnet/aspnetcore#5944.

Version introduced

3.0

Old behavior

WebHostBuilder provides ObjectPoolProvider by default in the DI container.

New behavior

WebHostBuilder no longer provides ObjectPoolProvider by default in the DI container.

Reason for change

This change was made to make ASP.NET Core more pay for play.

If your component requires ObjectPoolProvider, it needs to be added to your dependencies via the IServiceCollection.

Category

ASP.NET Core

Affected APIs

None


HTTP: DefaultHttpContext extensibility removed

As part of ASP.NET Core 3.0 performance improvements, the extensibility of DefaultHttpContext was removed. The class is now sealed. For more information, see dotnet/aspnetcore#6504.

If your unit tests use Mock<DefaultHttpContext>, use Mock<HttpContext> or new DefaultHttpContext() instead.

For discussion, see dotnet/aspnetcore#6534.

Version introduced

3.0

Old behavior

Classes can derive from DefaultHttpContext.

New behavior

Classes can't derive from DefaultHttpContext.

Reason for change

The extensibility was provided initially to allow pooling of the HttpContext, but it introduced unnecessary complexity and impeded other optimizations.

If you're using Mock<DefaultHttpContext> in your unit tests, begin using Mock<HttpContext> instead.

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.Http.DefaultHttpContext


HTTP: HeaderNames constants changed to static readonly

Starting in ASP.NET Core 3.0 Preview 5, the fields in Microsoft.Net.Http.Headers.HeaderNames changed from const to static readonly.

For discussion, see dotnet/aspnetcore#9514.

Version introduced

3.0

Old behavior

These fields used to be const.

New behavior

These fields are now static readonly.

Reason for change

The change:

  • Prevents the values from being embedded across assembly boundaries, allowing for value corrections as needed.
  • Enables faster reference equality checks.

Recompile against 3.0. Source code using these fields in the following ways can no longer do so:

  • As an attribute argument
  • As a case in a switch statement
  • When defining another const

To work around the breaking change, switch to using self-defined header name constants or string literals.

Category

ASP.NET Core

Affected APIs

Microsoft.Net.Http.Headers.HeaderNames


HTTP: Response body infrastructure changes

The infrastructure backing an HTTP response body has changed. If you're using HttpResponse directly, you shouldn't need to make any code changes. Read further if you're wrapping or replacing HttpResponse.Body or accessing HttpContext.Features.

Version introduced

3.0

Old behavior

There were three APIs associated with the HTTP response body:

  • IHttpResponseFeature.Body
  • IHttpSendFileFeature.SendFileAsync
  • IHttpBufferingFeature.DisableResponseBuffering

New behavior

If you replace HttpResponse.Body, it replaces the entire IHttpResponseBodyFeature with a wrapper around your given stream using StreamResponseBodyFeature to provide default implementations for all of the expected APIs. Setting back the original stream reverts this change.

Reason for change

The motivation is to combine the response body APIs into a single new feature interface.

Use IHttpResponseBodyFeature where you previously were using IHttpResponseFeature.Body, IHttpSendFileFeature, or IHttpBufferingFeature.

Category

ASP.NET Core

Affected APIs


SameSite is an option for cookies that can help mitigate some Cross-Site Request Forgery (CSRF) attacks. When this option was initially introduced, inconsistent defaults were used across various ASP.NET Core APIs. The inconsistency has led to confusing results. As of ASP.NET Core 3.0, these defaults are better aligned. You must opt in to this feature on a per-component basis.

Version introduced

3.0

Old behavior

Similar ASP.NET Core APIs used different default SameSiteMode values. An example of the inconsistency is seen in HttpResponse.Cookies.Append(String, String) and HttpResponse.Cookies.Append(String, String, CookieOptions), which defaulted to SameSiteMode.None and SameSiteMode.Lax, respectively.

New behavior

All the affected APIs default to SameSiteMode.None.

Reason for change

The default value was changed to make SameSite an opt-in feature.

Each component that emits cookies needs to decide if SameSite is appropriate for its scenarios. Review your usage of the affected APIs and reconfigure SameSite as needed.

Category

ASP.NET Core

Affected APIs


HTTP: Synchronous IO disabled in all servers

Starting with ASP.NET Core 3.0, synchronous server operations are disabled by default.

Change description

AllowSynchronousIO is an option in each server that enables or disables synchronous IO APIs like HttpRequest.Body.Read, HttpResponse.Body.Write, and Stream.Flush. These APIs have long been a source of thread starvation and app hangs. Starting in ASP.NET Core 3.0 Preview 3, these synchronous operations are disabled by default.

Affected servers:

  • Kestrel
  • HttpSys
  • IIS in-process
  • TestServer

Expect errors similar to:

  • Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
  • Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
  • Synchronous operations are disallowed. Call FlushAsync or set AllowSynchronousIO to true instead.

Each server has an AllowSynchronousIO option that controls this behavior and the default for all of them is now false.

The behavior can also be overridden on a per-request basis as a temporary mitigation. For example:

var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();
if (syncIOFeature != null)
{
    syncIOFeature.AllowSynchronousIO = true;
}

If you have trouble with a TextWriter or another stream calling a synchronous API in Dispose, call the new DisposeAsync API instead.

For discussion, see dotnet/aspnetcore#7644.

Version introduced

3.0

Old behavior

HttpRequest.Body.Read, HttpResponse.Body.Write, and Stream.Flush were allowed by default.

New behavior

These synchronous APIs are disallowed by default:

Expect errors similar to:

  • Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
  • Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
  • Synchronous operations are disallowed. Call FlushAsync or set AllowSynchronousIO to true instead.

Reason for change

These synchronous APIs have long been a source of thread starvation and app hangs. Starting in ASP.NET Core 3.0 Preview 3, the synchronous operations are disabled by default.

Use the asynchronous versions of the methods. The behavior can also be overridden on a per-request basis as a temporary mitigation.

var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();
if (syncIOFeature != null)
{
    syncIOFeature.AllowSynchronousIO = true;
}

Category

ASP.NET Core

Affected APIs


Identity: AddDefaultUI method overload removed

Starting with ASP.NET Core 3.0, the IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder,UIFramework) method overload no longer exists.

Version introduced

3.0

Reason for change

This change was a result of adoption of the static web assets feature.

Call IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder) instead of the overload that takes two arguments. If you're using Bootstrap 3, also add the following line to a <PropertyGroup> element in your project file:

<IdentityUIFrameworkVersion>Bootstrap3</IdentityUIFrameworkVersion>

Category

ASP.NET Core

Affected APIs

IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder,UIFramework)


Identity: Default Bootstrap version of UI changed

Starting in ASP.NET Core 3.0, Identity UI defaults to using version 4 of Bootstrap.

Version introduced

3.0

Old behavior

The services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(); method call was the same as services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(UIFramework.Bootstrap3);

New behavior

The services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(); method call is the same as services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(UIFramework.Bootstrap4);

Reason for change

Bootstrap 4 was released during ASP.NET Core 3.0 timeframe.

You're impacted by this change if you use the default Identity UI and have added it in Startup.ConfigureServices as shown in the following example:

services.AddDefaultIdentity<IdentityUser>().AddDefaultUI();

Take one of the following actions:

  • Migrate your app to use Bootstrap 4 using their migration guide.

  • Update Startup.ConfigureServices to enforce usage of Bootstrap 3. For example:

    services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(UIFramework.Bootstrap3);
    

Category

ASP.NET Core

Affected APIs

None


Identity: SignInAsync throws exception for unauthenticated identity

By default, SignInAsync throws an exception for principals / identities in which IsAuthenticated is false.

Version introduced

3.0

Old behavior

SignInAsync accepts any principals / identities, including identities in which IsAuthenticated is false.

New behavior

By default, SignInAsync throws an exception for principals / identities in which IsAuthenticated is false. There's a new flag to suppress this behavior, but the default behavior has changed.

Reason for change

The old behavior was problematic because, by default, these principals were rejected by [Authorize] / RequireAuthenticatedUser().

In ASP.NET Core 3.0 Preview 6, there's a RequireAuthenticatedSignIn flag on AuthenticationOptions that is true by default. Set this flag to false to restore the old behavior.

Category

ASP.NET Core

Affected APIs

None


Identity: SignInManager constructor accepts new parameter

Starting with ASP.NET Core 3.0, a new IUserConfirmation<TUser> parameter was added to the SignInManager constructor. For more information, see dotnet/aspnetcore#8356.

Version introduced

3.0

Reason for change

The motivation for the change was to add support for new email / confirmation flows in Identity.

If manually constructing a SignInManager, provide an implementation of IUserConfirmation or grab one from dependency injection to provide.

Category

ASP.NET Core

Affected APIs

SignInManager<TUser>


Identity: UI uses static web assets feature

ASP.NET Core 3.0 introduced a static web assets feature, and Identity UI has adopted it.

Change description

As a result of Identity UI adopting the static web assets feature:

  • Framework selection is accomplished by using the IdentityUIFrameworkVersion property in your project file.
  • Bootstrap 4 is the default UI framework for Identity UI. Bootstrap 3 has reached end of life, and you should consider migrating to a supported version.

Version introduced

3.0

Old behavior

The default UI framework for Identity UI was Bootstrap 3. The UI framework could be configured using a parameter to the AddDefaultUI method call in Startup.ConfigureServices.

New behavior

The default UI framework for Identity UI is Bootstrap 4. The UI framework must be configured in your project file, instead of in the AddDefaultUI method call.

Reason for change

Adoption of the static web assets feature required that the UI framework configuration move to MSBuild. The decision on which framework to embed is a build-time decision, not a runtime decision.

Review your site UI to ensure the new Bootstrap 4 components are compatible. If necessary, use the IdentityUIFrameworkVersion MSBuild property to revert to Bootstrap 3. Add the property to a <PropertyGroup> element in your project file:

<IdentityUIFrameworkVersion>Bootstrap3</IdentityUIFrameworkVersion>

Category

ASP.NET Core

Affected APIs

IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder, UIFramework)


Kestrel: Connection adapters removed

As part of the move to move "pubternal" APIs to public, the concept of an IConnectionAdapter was removed from Kestrel. Connection adapters are being replaced with connection middleware (similar to HTTP middleware in the ASP.NET Core pipeline, but for lower-level connections). HTTPS and connection logging have moved from connection adapters to connection middleware. Those extension methods should continue to work seamlessly, but the implementation details have changed.

For more information, see dotnet/aspnetcore#11412. For discussion, see dotnet/aspnetcore#11475.

Version introduced

3.0

Old behavior

Kestrel extensibility components were created using IConnectionAdapter.

New behavior

Kestrel extensibility components are created as middleware.

Reason for change

This change is intended to provide a more flexible extensibility architecture.

Convert any implementations of IConnectionAdapter to use the new middleware pattern as shown here.

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter


Kestrel: Empty HTTPS assembly removed

The assembly Microsoft.AspNetCore.Server.Kestrel.Https has been removed.

Version introduced

3.0

Reason for change

In ASP.NET Core 2.1, the contents of Microsoft.AspNetCore.Server.Kestrel.Https were moved to Microsoft.AspNetCore.Server.Kestrel.Core. This change was done in a non-breaking way using [TypeForwardedTo] attributes.

  • Libraries referencing Microsoft.AspNetCore.Server.Kestrel.Https 2.0 should update all ASP.NET Core dependencies to 2.1 or later. Otherwise, they may break when loaded into an ASP.NET Core 3.0 app.
  • Apps and libraries targeting ASP.NET Core 2.1 and later should remove any direct references to the Microsoft.AspNetCore.Server.Kestrel.Https NuGet package.

Category

ASP.NET Core

Affected APIs

None


Kestrel: Request trailer headers moved to new collection

In prior versions, Kestrel added HTTP/1.1 chunked trailer headers into the request headers collection when the request body was read to the end. This behavior caused concerns about ambiguity between headers and trailers. The decision was made to move the trailers to a new collection.

HTTP/2 request trailers were unavailable in ASP.NET Core 2.2 but are now also available in this new collection in ASP.NET Core 3.0.

New request extension methods have been added to access these trailers.

HTTP/1.1 trailers are available once the entire request body has been read.

HTTP/2 trailers are available once they're received from the client. The client won't send the trailers until the entire request body has been at least buffered by the server. You may need to read the request body to free up buffer space. Trailers are always available if you read the request body to the end. The trailers mark the end of the body.

Version introduced

3.0

Old behavior

Request trailer headers would be added to the HttpRequest.Headers collection.

New behavior

Request trailer headers aren't present in the HttpRequest.Headers collection. Use the following extension methods on HttpRequest to access them:

  • GetDeclaredTrailers() - Gets the request "Trailer" header that lists which trailers to expect after the body.
  • SupportsTrailers() - Indicates if the request supports receiving trailer headers.
  • CheckTrailersAvailable() - Determines if the request supports trailers and if they're available for reading.
  • GetTrailer(string trailerName) - Gets the requested trailing header from the response.

Reason for change

Trailers are a key feature in scenarios like gRPC. Merging the trailers in to request headers was confusing to users.

Use the trailer-related extension methods on HttpRequest to access trailers.

Category

ASP.NET Core

Affected APIs

HttpRequest.Headers


Kestrel: Transport abstractions removed and made public

As part of moving away from "pubternal" APIs, the Kestrel transport layer APIs are exposed as a public interface in the Microsoft.AspNetCore.Connections.Abstractions library.

Version introduced

3.0

Old behavior

  • Transport-related abstractions were available in the Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions library.
  • The ListenOptions.NoDelay property was available.

New behavior

  • The IConnectionListener interface was introduced in the Microsoft.AspNetCore.Connections.Abstractions library to expose the most used functionality from the ...Transport.Abstractions library.
  • The NoDelay is now available in transport options (LibuvTransportOptions and SocketTransportOptions).
  • SchedulingMode is no longer available.

Reason for change

ASP.NET Core 3.0 has moved away from "pubternal" APIs.

Category

ASP.NET Core

Affected APIs

None


Localization: ResourceManagerWithCultureStringLocalizer and WithCulture marked obsolete

The ResourceManagerWithCultureStringLocalizer class and WithCulture interface member are often sources of confusion for users of localization, especially when creating their own IStringLocalizer implementation. These items give the user the impression that an IStringLocalizer instance is "per-language, per-resource". In reality, the instances should only be "per-resource". The language searched for is determined by the CultureInfo.CurrentUICulture at execution time. To eliminate the source of confusion, the APIs were marked as obsolete in ASP.NET Core 3.0 Preview 3. The APIs will be removed in a future release.

For context, see dotnet/aspnetcore#3324. For discussion, see dotnet/aspnetcore#7756.

Version introduced

3.0

Old behavior

Methods weren't marked as Obsolete.

New behavior

Methods are marked Obsolete.

Reason for change

The APIs represented a use case that isn't recommended. There was confusion about the design of localization.

The recommendation is to use ResourceManagerStringLocalizer instead. Let the culture be set by the CurrentCulture. If that isn't an option, create and use a copy of ResourceManagerWithCultureStringLocalizer.

Category

ASP.NET Core

Affected APIs


Logging: DebugLogger class made internal

Prior to ASP.NET Core 3.0, DebugLogger's access modifier was public. In ASP.NET Core 3.0, the access modifier changed to internal.

Version introduced

3.0

Reason for change

The change is being made to:

  • Enforce consistency with other logger implementations such as ConsoleLogger.
  • Reduce the API surface.

Use the AddDebug ILoggingBuilder extension method to enable debug logging. DebugLoggerProvider is also still public in the event the service needs to be registered manually.

Category

ASP.NET Core

Affected APIs

Microsoft.Extensions.Logging.Debug.DebugLogger


MVC: Async suffix trimmed from controller action names

As part of addressing dotnet/aspnetcore#4849, ASP.NET Core MVC trims the suffix Async from action names by default. Starting with ASP.NET Core 3.0, this change affects both routing and link generation.

Version introduced

3.0

Old behavior

Consider the following ASP.NET Core MVC controller:

public class ProductController : Controller
{
    public async IActionResult ListAsync()
    {
        var model = await DbContext.Products.ToListAsync();
        return View(model);
    }
}

The action is routable via Product/ListAsync. Link generation requires specifying the Async suffix. For example:

<a asp-controller="Product" asp-action="ListAsync">List</a>

New behavior

In ASP.NET Core 3.0, the action is routable via Product/List. Link generation code should omit the Async suffix. For example:

<a asp-controller="Product" asp-action="List">List</a>

This change doesn't affect names specified using the [ActionName] attribute. The new behavior can be disabled by setting MvcOptions.SuppressAsyncSuffixInActionNames to false in Startup.ConfigureServices:

services.AddMvc(options =>
{
   options.SuppressAsyncSuffixInActionNames = false;
});

Reason for change

By convention, asynchronous .NET methods are suffixed with Async. However, when a method defines an MVC action, it's undesirable to use the Async suffix.

If your app depends on MVC actions preserving the name's Async suffix, choose one of the following mitigations:

  • Use the [ActionName] attribute to preserve the original name.
  • Disable the renaming entirely by setting MvcOptions.SuppressAsyncSuffixInActionNames to false in Startup.ConfigureServices:
services.AddMvc(options =>
{
   options.SuppressAsyncSuffixInActionNames = false;
});

Category

ASP.NET Core

Affected APIs

None


MVC: JsonResult moved to Microsoft.AspNetCore.Mvc.Core

JsonResult has moved to the Microsoft.AspNetCore.Mvc.Core assembly. This type used to be defined in Microsoft.AspNetCore.Mvc.Formatters.Json. An assembly-level [TypeForwardedTo] attribute was added to Microsoft.AspNetCore.Mvc.Formatters.Json to address this issue for the majority of users. Apps that use third-party libraries may encounter issues.

Version introduced

3.0 Preview 6

Old behavior

An app using a 2.2-based library builds successfully.

New behavior

An app using a 2.2-based library fails compilation. An error containing a variation of the following text is provided:

The type 'JsonResult' exists in both 'Microsoft.AspNetCore.Mvc.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' and 'Microsoft.AspNetCore.Mvc.Formatters.Json, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'

For an example of such an issue, see dotnet/aspnetcore#7220.

Reason for change

Platform-level changes to the composition of ASP.NET Core as described at aspnet/Announcements#325.

Libraries compiled against the 2.2 version of Microsoft.AspNetCore.Mvc.Formatters.Json may need to recompile to address the problem for all consumers. If affected, contact the library author. Request recompilation of the library to target ASP.NET Core 3.0.

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.Mvc.JsonResult


MVC: Precompilation tool deprecated

In ASP.NET Core 1.1, the Microsoft.AspNetCore.Mvc.Razor.ViewCompilation (MVC precompilation tool) package was introduced to add support for publish-time compilation of Razor files (.cshtml files). In ASP.NET Core 2.1, the Razor SDK was introduced to expand upon features of the precompilation tool. The Razor SDK added support for build- and publish-time compilation of Razor files. The SDK verifies the correctness of .cshtml files at build time while improving on app startup time. The Razor SDK is on by default, and no gesture is required to start using it.

In ASP.NET Core 3.0, the ASP.NET Core 1.1-era MVC precompilation tool was removed. Earlier package versions will continue receiving important bug and security fixes in the patch release.

Version introduced

3.0

Old behavior

The Microsoft.AspNetCore.Mvc.Razor.ViewCompilation package was used to pre-compile MVC Razor views.

New behavior

The Razor SDK natively supports this functionality. The Microsoft.AspNetCore.Mvc.Razor.ViewCompilation package is no longer updated.

Reason for change

The Razor SDK provides more functionality and verifies the correctness of .cshtml files at build time. The SDK also improves app startup time.

For users of ASP.NET Core 2.1 or later, update to use the native support for precompilation in the Razor SDK. If bugs or missing features prevent migration to the Razor SDK, open an issue at dotnet/aspnetcore.

Category

ASP.NET Core

Affected APIs

None


MVC: "Pubternal" types changed to internal

In ASP.NET Core 3.0, all "pubternal" types in MVC were updated to either be public in a supported namespace or internal as appropriate.

Change description

In ASP.NET Core, "pubternal" types are declared as public but reside in a .Internal-suffixed namespace. While these types are public, they have no support policy and are subject to breaking changes. Unfortunately, accidental use of these types has been common, resulting in breaking changes to these projects and limiting the ability to maintain the framework.

Version introduced

3.0

Old behavior

Some types in MVC were public but in a .Internal namespace. These types had no support policy and were subject to breaking changes.

New behavior

All such types are updated either to be public in a supported namespace or marked as internal.

Reason for change

Accidental use of the "pubternal" types has been common, resulting in breaking changes to these projects and limiting the ability to maintain the framework.

If you're using types that have become truly public and have been moved into a new, supported namespace, update your references to match the new namespaces.

If you're using types that have become marked as internal, you'll need to find an alternative. The previously "pubternal" types were never supported for public use. If there are specific types in these namespaces that are critical to your apps, file an issue at dotnet/aspnetcore. Considerations may be made for making the requested types public.

Category

ASP.NET Core

Affected APIs

This change includes types in the following namespaces:

  • Microsoft.AspNetCore.Mvc.Cors.Internal
  • Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
  • Microsoft.AspNetCore.Mvc.Formatters.Internal
  • Microsoft.AspNetCore.Mvc.Formatters.Json.Internal
  • Microsoft.AspNetCore.Mvc.Formatters.Xml.Internal
  • Microsoft.AspNetCore.Mvc.Internal
  • Microsoft.AspNetCore.Mvc.ModelBinding.Internal
  • Microsoft.AspNetCore.Mvc.Razor.Internal
  • Microsoft.AspNetCore.Mvc.RazorPages.Internal
  • Microsoft.AspNetCore.Mvc.TagHelpers.Internal
  • Microsoft.AspNetCore.Mvc.ViewFeatures.Internal

MVC: Web API compatibility shim removed

Starting with ASP.NET Core 3.0, the Microsoft.AspNetCore.Mvc.WebApiCompatShim package is no longer available.

Change description

The Microsoft.AspNetCore.Mvc.WebApiCompatShim (WebApiCompatShim) package provides partial compatibility in ASP.NET Core with ASP.NET 4.x Web API 2 to simplify migrating existing Web API implementations to ASP.NET Core. However, apps using the WebApiCompatShim don't benefit from the API-related features shipping in recent ASP.NET Core releases. Such features include improved Open API specification generation, standardized error handling, and client code generation. To better focus the API efforts in 3.0, WebApiCompatShim was removed. Existing apps using the WebApiCompatShim should migrate to the newer [ApiController] model.

Version introduced

3.0

Reason for change

The Web API compatibility shim was a migration tool. It restricts user access to new functionality added in ASP.NET Core.

Remove usage of this shim and migrate directly to the similar functionality in ASP.NET Core itself.

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.Mvc.WebApiCompatShim


Razor: RazorTemplateEngine API removed

The RazorTemplateEngine API was removed and replaced with RazorProjectEngine.

For discussion, see GitHub issue dotnet/aspnetcore#25215.

Version introduced

3.0

Old behavior

A template engine can be created and used to parse and generate code for Razor files.

New behavior

RazorProjectEngine can be created and provided the same type of information as RazorTemplateEngine to parse and generate code for Razor files. RazorProjectEngine also provides extra levels of configuration.

Reason for change

RazorTemplateEngine was too tightly coupled to the existing implementations. This tight coupling led to more questions when trying to properly configure a Razor parsing/generation pipeline.

Use RazorProjectEngine instead of RazorTemplateEngine. Consider the following examples.

Create and configure the RazorProjectEngine
RazorProjectEngine projectEngine =
    RazorProjectEngine.Create(RazorConfiguration.Default,
        RazorProjectFileSystem.Create(@"C:\source\repos\ConsoleApp4\ConsoleApp4"),
        builder =>
        {
            builder.ConfigureClass((document, classNode) =>
            {
                classNode.ClassName = "MyClassName";

                // Can also configure other aspects of the class here.
            });

            // More configuration can go here
        });
Generate code for a Razor file
RazorProjectItem item = projectEngine.FileSystem.GetItem(
    @"C:\source\repos\ConsoleApp4\ConsoleApp4\Example.cshtml",
    FileKinds.Legacy);
RazorCodeDocument output = projectEngine.Process(item);

// Things available
RazorSyntaxTree syntaxTree = output.GetSyntaxTree();
DocumentIntermediateNode intermediateDocument =
    output.GetDocumentIntermediateNode();
RazorCSharpDocument csharpDocument = output.GetCSharpDocument();

Category

ASP.NET Core

Affected APIs


Razor: Runtime compilation moved to a package

Support for runtime compilation of Razor views and Razor Pages has moved to a separate package.

Version introduced

3.0

Old behavior

Runtime compilation is available without needing additional packages.

New behavior

The functionality has been moved to the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package.

The following APIs were previously available in Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions to support runtime compilation. The APIs are now available via Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.MvcRazorRuntimeCompilationOptions.

  • RazorViewEngineOptions.FileProviders is now MvcRazorRuntimeCompilationOptions.FileProviders
  • RazorViewEngineOptions.AdditionalCompilationReferences is now MvcRazorRuntimeCompilationOptions.AdditionalReferencePaths

In addition, Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions.AllowRecompilingViewsOnFileChange has been removed. Recompilation on file changes is enabled by default by referencing the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package.

Reason for change

This change was necessary to remove the ASP.NET Core shared framework dependency on Roslyn.

Apps that require runtime compilation or recompilation of Razor files should take the following steps:

  1. Add a reference to the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package.

  2. Update the project's Startup.ConfigureServices method to include a call to AddRazorRuntimeCompilation. For example:

    services.AddMvc()
        .AddRazorRuntimeCompilation();
    

Category

ASP.NET Core

Affected APIs

Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions


Session state: Obsolete APIs removed

Obsolete APIs for configuring session cookies were removed. For more information, see aspnet/Announcements#257.

Version introduced

3.0

Reason for change

This change enforces consistency across APIs for configuring features that use cookies.

Migrate usage of the removed APIs to their newer replacements. Consider the following example in Startup.ConfigureServices:

public void ConfigureServices(ServiceCollection services)
{
    services.AddSession(options =>
    {
        // Removed obsolete APIs
        options.CookieName = "SessionCookie";
        options.CookieDomain = "contoso.com";
        options.CookiePath = "/";
        options.CookieHttpOnly = true;
        options.CookieSecure = CookieSecurePolicy.Always;

        // new API
        options.Cookie.Name = "SessionCookie";
        options.Cookie.Domain = "contoso.com";
        options.Cookie.Path = "/";
        options.Cookie.HttpOnly = true;
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    });
}

Category

ASP.NET Core

Affected APIs


Shared framework: Assemblies removed from Microsoft.AspNetCore.App

Starting in ASP.NET Core 3.0, the ASP.NET Core shared framework (Microsoft.AspNetCore.App) only contains first-party assemblies that are fully developed, supported, and serviceable by Microsoft.

Change description

Think of the change as the redefining of boundaries for the ASP.NET Core "platform." The shared framework will be source-buildable by anybody via GitHub and will continue to offer the existing benefits of .NET Core shared frameworks to your apps. Some benefits include smaller deployment size, centralized patching, and faster startup time.

As part of the change, some notable breaking changes are introduced in Microsoft.AspNetCore.App.

Version introduced

3.0

Old behavior

Projects referenced Microsoft.AspNetCore.App via a <PackageReference> element in the project file.

Additionally, Microsoft.AspNetCore.App contained the following subcomponents:

  • Json.NET (Newtonsoft.Json)
  • Entity Framework Core (assemblies prefixed with Microsoft.EntityFrameworkCore.)
  • Roslyn (Microsoft.CodeAnalysis)

New behavior

A reference to Microsoft.AspNetCore.App no longer requires a <PackageReference> element in the project file. The .NET Core SDK supports a new element called <FrameworkReference>, which replaces the use of <PackageReference>.

For more information, see dotnet/aspnetcore#3612.

Entity Framework Core ships as NuGet packages. This change aligns the shipping model with all other data access libraries on .NET. It provides Entity Framework Core the simplest path to continue innovating while supporting the various .NET platforms. The move of Entity Framework Core out of the shared framework has no impact on its status as a Microsoft-developed, supported, and serviceable library. The .NET Core support policy continues to cover it.

Json.NET and Entity Framework Core continue to work with ASP.NET Core. They won't, however, be included in the shared framework.

For more information, see The future of JSON in .NET Core 3.0. Also see the complete list of binaries removed from the shared framework.

Reason for change

This change simplifies the consumption of Microsoft.AspNetCore.App and reduces the duplication between NuGet packages and shared frameworks.

For more information on the motivation for this change, see this blog post.

It won't be necessary for projects to consume assemblies in Microsoft.AspNetCore.App as NuGet packages. To simplify the targeting and usage of the ASP.NET Core shared framework, many NuGet packages shipped since ASP.NET Core 1.0 are no longer produced. The APIs those packages provide are still available to apps by using a <FrameworkReference> to Microsoft.AspNetCore.App. Common API examples include Kestrel, MVC, and Razor.

This change doesn't apply to all binaries referenced via Microsoft.AspNetCore.App in ASP.NET Core 2.x. Notable exceptions include:

  • Microsoft.Extensions libraries that continue to target .NET Standard will be available as NuGet packages (see https://github.com/dotnet/extensions).
  • APIs produced by the ASP.NET Core team that aren't part of Microsoft.AspNetCore.App. For example, the following components are available as NuGet packages:
  • Extensions to MVC that maintain support for Json.NET. An API will be provided as a NuGet package to support using Json.NET and MVC.
  • The SignalR .NET client will continue to support .NET Standard and ship as a NuGet package. It's intended for use on many .NET runtimes, such as Xamarin and UWP.

For more information, see Stop producing packages for shared framework assemblies in 3.0. For discussion, see dotnet/aspnetcore#3757.

Category

ASP.NET Core

Affected APIs


Shared framework: Removed Microsoft.AspNetCore.All

Starting in ASP.NET Core 3.0, the Microsoft.AspNetCore.All metapackage and the matching Microsoft.AspNetCore.All shared framework are no longer produced. This package is available in ASP.NET Core 2.2 and will continue to receive servicing updates in ASP.NET Core 2.1.

Version introduced

3.0

Old behavior

Apps could use the Microsoft.AspNetCore.All metapackage to target the Microsoft.AspNetCore.All shared framework on .NET Core.

New behavior

.NET Core 3.0 doesn't include a Microsoft.AspNetCore.All shared framework.

Reason for change

The Microsoft.AspNetCore.All metapackage included a large number of external dependencies.

Migrate your project to use the Microsoft.AspNetCore.App framework. Components that were previously available in Microsoft.AspNetCore.All are still available on NuGet. Those components are now deployed with your app instead of being included in the shared framework.

Category

ASP.NET Core

Affected APIs

None


SignalR: HandshakeProtocol.SuccessHandshakeData replaced

The HandshakeProtocol.SuccessHandshakeData field was removed and replaced with a helper method that generates a successful handshake response given a specific IHubProtocol.

Version introduced

3.0

Old behavior

HandshakeProtocol.SuccessHandshakeData was a public static ReadOnlyMemory<byte> field.

New behavior

HandshakeProtocol.SuccessHandshakeData has been replaced by a static GetSuccessfulHandshake(IHubProtocol protocol) method that returns a ReadOnlyMemory<byte> based on the specified protocol.

Reason for change

Additional fields were added to the handshake response that are non-constant and change depending on the selected protocol.

None. This type isn't designed for use from user code. It's public, so it can be shared between the SignalR server and client. It may also be used by customer SignalR clients written in .NET. Users of SignalR shouldn't be affected by this change.

Category

ASP.NET Core

Affected APIs

HandshakeProtocol.SuccessHandshakeData


SignalR: HubConnection ResetSendPing and ResetTimeout methods removed

The ResetSendPing and ResetTimeout methods were removed from the SignalR HubConnection API. These methods were originally intended only for internal use but were made public in ASP.NET Core 2.2. These methods won't be available starting in the ASP.NET Core 3.0 Preview 4 release. For discussion, see dotnet/aspnetcore#8543.

Version introduced

3.0

Old behavior

APIs were available.

New behavior

APIs are removed.

Reason for change

These methods were originally intended only for internal use but were made public in ASP.NET Core 2.2.

Don't use these methods.

Category

ASP.NET Core

Affected APIs


SignalR: HubConnectionContext constructors changed

SignalR's HubConnectionContext constructors changed to accept an options type, rather than multiple parameters, to future-proof adding options. This change replaces two constructors with a single constructor that accepts an options type.

Version introduced

3.0

Old behavior

HubConnectionContext has two constructors:

public HubConnectionContext(ConnectionContext connectionContext, TimeSpan keepAliveInterval, ILoggerFactory loggerFactory);
public HubConnectionContext(ConnectionContext connectionContext, TimeSpan keepAliveInterval, ILoggerFactory loggerFactory, TimeSpan clientTimeoutInterval);

New behavior

The two constructors were removed and replaced with one constructor:

public HubConnectionContext(ConnectionContext connectionContext, HubConnectionContextOptions contextOptions, ILoggerFactory loggerFactory)

Reason for change

The new constructor uses a new options object. Consequently, the features of HubConnectionContext can be expanded in the future without making more constructors and breaking changes.

Instead of using the following constructor:

HubConnectionContext connectionContext = new HubConnectionContext(
    connectionContext,
    keepAliveInterval: TimeSpan.FromSeconds(15),
    loggerFactory,
    clientTimeoutInterval: TimeSpan.FromSeconds(15));

Use the following constructor:

HubConnectionContextOptions contextOptions = new HubConnectionContextOptions()
{
    KeepAliveInterval = TimeSpan.FromSeconds(15),
    ClientTimeoutInterval = TimeSpan.FromSeconds(15)
};
HubConnectionContext connectionContext = new HubConnectionContext(connectionContext, contextOptions, loggerFactory);

Category

ASP.NET Core

Affected APIs


SignalR: JavaScript client package name changed

In ASP.NET Core 3.0 Preview 7, the SignalR JavaScript client package name changed from @aspnet/signalr to @microsoft/signalr. The name change reflects the fact that SignalR is useful in more than just ASP.NET Core apps, thanks to the Azure SignalR Service.

To react to this change, change references in your package.json files, require statements, and ECMAScript import statements. No API will change as part of this rename.

For discussion, see dotnet/aspnetcore#11637.

Version introduced

3.0

Old behavior

The client package was named @aspnet/signalr.

New behavior

The client package is named @microsoft/signalr.

Reason for change

The name change clarifies that SignalR is useful beyond ASP.NET Core apps, thanks to the Azure SignalR Service.

Switch to the new package @microsoft/signalr.

Category

ASP.NET Core

Affected APIs

None


SignalR: UseSignalR and UseConnections methods marked obsolete

The methods UseConnections and UseSignalR and the classes ConnectionsRouteBuilder and HubRouteBuilder are marked as obsolete in ASP.NET Core 3.0.

Version introduced

3.0

Old behavior

SignalR hub routing was configured using UseSignalR or UseConnections.

New behavior

The old way of configuring routing has been obsoleted and replaced with endpoint routing.

Reason for change

Middleware is being moved to the new endpoint routing system. The old way of adding middleware is being obsoleted.

Replace UseSignalR with UseEndpoints:

Old code:

app.UseSignalR(routes =>
{
    routes.MapHub<SomeHub>("/path");
});

New code:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHub<SomeHub>("/path");
});

Category

ASP.NET Core

Affected APIs


SPAs: SpaServices and NodeServices marked obsolete

The contents of the following NuGet packages have all been unnecessary since ASP.NET Core 2.1. Consequently, the following packages are being marked as obsolete:

For the same reason, the following npm modules are being marked as deprecated:

The preceding packages and npm modules will later be removed in .NET 5.

Version introduced

3.0

Old behavior

The deprecated packages and npm modules were intended to integrate ASP.NET Core with various Single-Page App (SPA) frameworks. Such frameworks include Angular, React, and React with Redux.

New behavior

A new integration mechanism exists in the Microsoft.AspNetCore.SpaServices.Extensions NuGet package. The package remains the basis of the Angular and React project templates since ASP.NET Core 2.1.

Reason for change

ASP.NET Core supports integration with various Single-Page App (SPA) frameworks, including Angular, React, and React with Redux. Initially, integration with these frameworks was accomplished with ASP.NET Core-specific components that handled scenarios like server-side prerendering and integration with Webpack. As time went on, industry standards changed. Each of the SPA frameworks released their own standard command-line interfaces. For example, Angular CLI and create-react-app.

When ASP.NET Core 2.1 was released in May 2018, the team responded to the change in standards. A newer and simpler way to integrate with the SPA frameworks' own toolchains was provided. The new integration mechanism exists in the package Microsoft.AspNetCore.SpaServices.Extensions and remains the basis of the Angular and React project templates since ASP.NET Core 2.1.

To clarify that the older ASP.NET Core-specific components are irrelevant and not recommended:

  • The pre-2.1 integration mechanism is marked as obsolete.
  • The supporting npm packages are marked as deprecated.

If you're using these packages, update your apps to use the functionality:

  • In the Microsoft.AspNetCore.SpaServices.Extensions package.
  • Provided by the SPA frameworks you're using

To enable features like server-side prerendering and hot module reload, see the documentation for the corresponding SPA framework. The functionality in Microsoft.AspNetCore.SpaServices.Extensions is not obsolete and will continue to be supported.

Category

ASP.NET Core

Affected APIs


SPAs: SpaServices and NodeServices no longer fall back to console logger

Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices won't display console logs unless logging is configured.

Version introduced

3.0

Old behavior

Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices used to automatically create a console logger when logging isn't configured.

New behavior

Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices won't display console logs unless logging is configured.

Reason for change

There's a need to align with how other ASP.NET Core packages implement logging.

If the old behavior is required, to configure console logging, add services.AddLogging(builder => builder.AddConsole()) to your Setup.ConfigureServices method.

Category

ASP.NET Core

Affected APIs

None


Target framework: .NET Framework support dropped

Starting with ASP.NET Core 3.0, .NET Framework is an unsupported target framework.

Change description

.NET Framework 4.8 is the last major version of .NET Framework. New ASP.NET Core apps should be built on .NET Core. Starting with the .NET Core 3.0 release, you can think of ASP.NET Core 3.0 as being part of .NET Core.

Customers using ASP.NET Core with .NET Framework can continue in a fully supported fashion using the 2.1 LTS release. Support and servicing for 2.1 continues until at least August 21, 2021. This date is three years after declaration of the LTS release per the .NET Support Policy. Support for ASP.NET Core 2.1 packages on .NET Framework will extend indefinitely, similar to the servicing policy for other package-based ASP.NET frameworks.

For more information about porting from .NET Framework to .NET Core, see Porting to .NET Core.

Microsoft.Extensions packages (such as logging, dependency injection, and configuration) and Entity Framework Core aren't affected. They'll continue to support .NET Standard.

For more information on the motivation for this change, see the original blog post.

Version introduced

3.0

Old behavior

ASP.NET Core apps could run on either .NET Core or .NET Framework.

New behavior

ASP.NET Core apps can only be run on .NET Core.

Take one of the following actions:

  • Keep your app on ASP.NET Core 2.1.
  • Migrate your app and dependencies to .NET Core.

Category

ASP.NET Core

Affected APIs

None