Breaking changes in .NET Core 3.1

If you're migrating to version 3.1 of .NET Core or ASP.NET Core, the breaking changes listed in this article may affect your app.

ASP.NET Core

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


Deployment

x86 host path on 64-bit Windows

MSBuild

Design-time builds only return top-level package references

Starting in .NET Core SDK 3.1.400, only top-level package references are returned by the RunResolvePackageDependencies target.

Version introduced

.NET Core SDK 3.1.400

Change description

In previous versions of the .NET Core SDK, the RunResolvePackageDependencies target created the following MSBuild items that contained information from the NuGet assets file:

  • PackageDefinitions
  • PackageDependencies
  • TargetDefinitions
  • FileDefinitions
  • FileDependencies

This data is used by Visual Studio to populate the Dependencies node in Solution Explorer. However, it can be a large amount of data, and the data isn't needed unless the Dependencies node is expanded.

Starting in the .NET Core SDK version 3.1.400, most of these items aren't generated by default. Only items of type Package are returned. If Visual Studio needs the items to populate the Dependencies node, it reads the information directly from the assets file.

Reason for change

This changed was introduced to improve solution-load performance inside of Visual Studio. Previously, all package references would be loaded, which involved loading many references that most users would never view.

If you have MSBuild logic that depends on these items being created, set the EmitLegacyAssetsFileItems property to true in your project file. This setting enables the previous behavior where all the items are created.

Category

MSBuild

Affected APIs

N/A


SDK

Tool manifests in root folder

Windows Forms

Removed controls

Starting in .NET Core 3.1, some Windows Forms controls are no longer available.

Change description

Starting with .NET Core 3.1, various Windows Forms controls are no longer available. Replacement controls that have better design and support were introduced in .NET Framework 2.0. The deprecated controls were previously removed from designer toolboxes but were still available to be used.

The following types are no longer available:

Version introduced

3.1

Each removed control has a recommended replacement control. Refer to the following table:

Removed control (API) Recommended replacement Associated APIs that are removed
ContextMenu ContextMenuStrip
DataGrid DataGridView DataGridCell, DataGridRow, DataGridTableCollection, DataGridColumnCollection, DataGridTableStyle, DataGridColumnStyle, DataGridLineStyle, DataGridParentRowsLabel, DataGridParentRowsLabelStyle, DataGridBoolColumn, DataGridTextBox, GridColumnStylesCollection, GridTableStylesCollection, HitTestType
MainMenu MenuStrip
Menu ToolStripDropDown, ToolStripDropDownMenu MenuItemCollection
MenuItem ToolStripMenuItem
ToolBar ToolStrip ToolBarAppearance
ToolBarButton ToolStripButton ToolBarButtonClickEventArgs, ToolBarButtonClickEventHandler, ToolBarButtonStyle, ToolBarTextAlign

Category

Windows Forms

Affected APIs


CellFormatting event not raised if tooltip is shown

A DataGridView now shows a cell's text and error tooltips when hovered by a mouse and when selected via the keyboard. If a tooltip is shown, the DataGridView.CellFormatting event is not raised.

Change description

Prior to .NET Core 3.1, a DataGridView that had the ShowCellToolTips property set to true showed a tooltip for a cell's text and errors when the cell was hovered by a mouse. Tooltips were not shown when a cell was selected via the keyboard (for example, by using the Tab key, shortcut keys, or arrow navigation). If the user edited a cell, and then, while the DataGridView was still in edit mode, hovered over a cell that did not have the ToolTipText property set, a CellFormatting event was raised to format the cell's text for display in the cell.

To meet accessibility standards, starting in .NET Core 3.1, a DataGridView that has the ShowCellToolTips property set to true shows tooltips for a cell's text and errors not only when the cell is hovered, but also when it's selected via the keyboard. As a consequence of this change, the CellFormatting event is not raised when cells that don't have the ToolTipText property set are hovered while the DataGridView is in edit mode. The event is not raised because the content of the hovered cell is shown as a tooltip instead of being displayed in the cell.

Version introduced

3.1

Refactor any code that depends on the CellFormatting event while the DataGridView is in edit mode.

Category

Windows Forms

Affected APIs

None


See also