Breaking changes for migration from Version 2.2 to 3.0

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

ASP.NET Core

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

Constructors

Properties

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 aspnet/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 aspnet/AspNetCore@d7a7c65.

For discussion, see aspnet/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 aspnet/AspNetCore#7105. For discussion, see aspnet/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: 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 aspnet/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 aspnet/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 aspnet/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 aspnet/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/aspnet/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/aspnet/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: 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 aspnet/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 aspnet/AspNetCore#6504.

If your unit tests use Mock<DefaultHttpContext>, use Mock<HttpContext> instead.

For discussion, see aspnet/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 aspnet/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 aspnet/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. 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

Microsoft.AspNetCore.Identity.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 aspnet/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>.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 aspnet/AspNetCore#11412. For discussion, see aspnet/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 aspnet/AspNetCore#3324. For discussion, see aspnet/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 aspnet/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: 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 aspnet/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 aspnet/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: 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 -> MvcRazorRuntimeCompilationOptions.FileProviders
  • RazorViewEngineOptions.AdditionalCompilationReferences -> 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 AddMvcRazorRuntimeCompilation. For example, in Startup.ConfigureServices:

    services.AddMvc()
        .AddMvcRazorRuntimeCompilation();
    

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 aspnet/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/aspnet/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 aspnet/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

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 aspnet/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 aspnet/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

CoreFx

APIs that report version now report product and not file version

Many of the APIs that return versions in .NET Core now returned the product version rather than the file version.

Change description

In .NET Core 2.2 and previous versions, methods such as Environment.Version, RuntimeInformation.FrameworkDescription, and the file properties dialog for .NET Core assemblies reflect the file version. Starting with .NET Core 3.0, they reflect the product version.

The following figure illustrates the difference in version information for the System.Runtime.dll assembly for .NET Core 2.2 (on the left) and .NET Core 3.0 (on the right) as displayed by the Windows Explorer file properties dialog.

Difference in product version information

Version introduced

3.0

None. This change should make version detection intuitive rather than obtuse.

Category

CoreFx

Affected APIs


Custom EncoderFallbackBuffer instances cannot fall back recursively

Custom EncoderFallbackBuffer instances cannot fall back recursively. The implementation of EncoderFallbackBuffer.GetNextChar() must result in a character sequence that is convertible to the destination encoding. Otherwise, an exception occurs.

Change description

During a character-to-byte transcoding operation, the runtime detects ill-formed or nonconvertible UTF-16 sequences and provides those characters to the EncoderFallbackBuffer.Fallback method. The Fallback method determines which characters should be substituted for the original nonconvertible data, and these characters are drained by calling EncoderFallbackBuffer.GetNextChar in a loop.

The runtime then attempts to transcode these substitution characters to the target encoding. If this operation succeeds, the runtime continues transcoding from where it left off in the original input string.

In .NET Core Preview 7 and earlier versions, custom implementations of EncoderFallbackBuffer.GetNextChar() can return character sequences that are not convertible to the destination encoding. If the substituted characters cannot be transcoded to the target encoding, the runtime invokes the EncoderFallbackBuffer.Fallback method once again with the substitution characters, expecting the EncoderFallbackBuffer.GetNextChar() method to return a new substitution sequence. This process continues until the runtime eventually sees a well-formed, convertible substitution, or until a maximum recursion count is reached.

Starting with .NET Core 3.0, custom implementations of EncoderFallbackBuffer.GetNextChar() must return character sequences that are convertible to the destination encoding. If the substituted characters cannot be transcoded to the target encoding, an ArgumentException is thrown. The runtime will no longer make recursive calls into the EncoderFallbackBuffer instance.

This behavior only applies when all three of the following conditions are met:

  • The runtime detects an ill-formed UTF-16 sequence or a UTF-16 sequence that cannot be converted to the target encoding.
  • A custom EncoderFallback has been specified.
  • The custom EncoderFallback attempts to substitute a new ill-formed or nonconvertible UTF-16 sequence.

Version introduced

3.0

Most developers needn't take any action.

If an application uses a custom EncoderFallback and EncoderFallbackBuffer class, ensure the implementation of EncoderFallbackBuffer.Fallback populates the fallback buffer with well-formed UTF-16 data that is directly convertible to the target encoding when the Fallback method is first invoked by the runtime.

Category

CoreFx

Affected APIs


Floating-point formatting and parsing behavior changed

Floating point parsing and formatting behavior (by the Double and Single types) are now IEEE-compliant.

Change description

In .NET Core 2.2 and earlier versions, formatting with Double.ToString and Single.ToString, and parsing with Double.Parse, Double.TryParse, Single.Parse, and Single.TryParse are not IEEE-compliant. As a result, it is impossible to guarantee that a value will roundtrip with any supported standard or custom format string. For some inputs, the attempt to parse a formatted value can fail, and for others, the parsed value doesn't equal the original value.

Starting with .NET Core 3.0, parsing and formatting operations are IEEE 754-compliant. This ensures that the behavior of floating-point types in .NET matches that of IEEE-compliant languages such as C#. For more information, see the Floating-point parsing and formatting improvements in .NET Core 3.0 blog post.

Version introduced

3.0

The "Potential impact to existing code" section of the Floating-point parsing and formatting improvements in .NET Core 3.0 blog post suggests changes to your code if you observe a change of behavior when compared to .NET Core 2.2 applications Generally, this involves using a different standard or custom format string to enforce the desired behavior. Some results may not have a workaround if they were previously incorrect.

Category

CoreFx

Affected APIs


Floating-point parsing operations no longer fail or throw an OverflowException

The floating-point parsing methods no longer throw an OverflowException or return false when they parse a string whose numeric value is outside the range of the Single or Double floating-point type.

Change description

In .NET Core 2.2 and earlier versions, the Double.Parse and Single.Parse methods throw an OverflowException for values that outside the range of their respective type. The Double.TryParse and Single.TryParse methods return false for the string representations of out-of-range numeric values.

Starting with .NET Core 3.0, the Double.Parse, Double.TryParse, Single.Parse, and Single.TryParse methods no longer fail when parsing out-of-range numeric strings. Instead, the Double parsing methods return Double.PositiveInfinity for values that exceed Double.MaxValue, and they return Double.NegativeInfinity for values that are less than Double.MinValue. Similarly, the Single parsing methods return Single.PositiveInfinity for values that exceed Single.MaxValue, and they return Single.NegativeInfinity for values that are less than Single.MinValue.

This change was made for improved IEEE 754:2008 compliance.

Version introduced

3.0

This change can affect your code in either of two ways:

  • Your code depends on the handler for the OverflowException to execute when an overflow occurs. In this case, you should remove the catch statement and place any necessary code in an If statement that tests whether Double.IsInfinity or Single.IsInfinity is true.

  • Your code assumes that floating-point values are not Infinity. In this case, you should add the necessary code to check for floating-point values of PositiveInfinity and NegativeInfinity.

Category

CoreFx

Affected APIs


InvalidAsynchronousStateException moved to another assembly

The InvalidAsynchronousStateException class has been moved.

Change description

In .NET Core 2.2 and earlier versions, the InvalidAsynchronousStateException class is found in the System.ComponentModel.TypeConverter assembly.

Starting with .NET Core 3.0, it is found in the System.ComponentModel.Primitives assembly.

Version introduced

3.0

This change only affects applications that use reflection to load the InvalidAsynchronousStateException by calling a method such as Assembly.GetType or an overload of Activator.CreateInstance that assumes the type is in a particular assembly. If that is the case, the assembly the assembly referenced in the method call should be updated to reflect the type's new assembly location.

Category

CoreFx

Affected APIs

  • None

.NET Core 3.0 follows Unicode best practices when replacing ill-formed UTF-8 byte sequences

When the UTF8Encoding class encounters an ill-formed UTF-8 byte sequence during a byte-to-character transcoding operation, it will replace that sequence with a '�' (U+FFFD REPLACEMENT CHARACTER) character in the output string. .NET Core 3.0 differs from previous versions of .NET Core and the .NET Framework by following the Unicode best practice for performing this replacement during the transcoding operation.

This is part of a larger effort to improve UTF-8 handling throughout .NET, including by the new System.Text.Unicode.Utf8 and System.Text.Rune types. The UTF8Encoding type was given improved error handling mechanics so that it produces output consistent with the newly introduced types.

Change description

Starting with .NET Core 3.0, when transcoding bytes to characters, the UTF8Encoding class performs character substitution based on Unicode best practices. The substitution mechanism used is described by The Unicode Standard, Version 12.0, Sec. 3.9 (PDF) in the heading titled U+FFFD Substitution of Maximal Subparts.

This behavior only applies when the input byte sequence contains ill-formed UTF-8 data. Additionally, if the UTF8Encoding instance has been constructed with throwOnInvalidBytes: true (see the [UTF8Encoding constructor documentation](UTF8Encoding(Boolean, Boolean), the UTF8Encoding instance will continue to throw on invalid input rather than perform U+FFFD replacement.

The following illustrates the impact of this change with an invalid 3-byte input:

Ill-formed 3-byte input Output before .NET Core 3.0 Output starting with .NET Core 3.0
[ ED A0 90 ] [ FFFD FFFD ] (2-character output) [ FFFD FFFD FFFD ] (3-character output)

This 3-char output is the preferred output, according to Table 3-9 of the previously linked Unicode Standard PDF.

Version introduced

3.0

No action is required on the part of the developer.

Category

CoreFx

Affected APIs


TypeDescriptionProviderAttribute moved to another assembly

The TypeDescriptionProviderAttribute class has been moved.

Change description

In .NET Core 2.2 and earlier versions, The TypeDescriptionProviderAttribute class is found in the System.ComponentModel.TypeConverter assembly.

Starting with .NET Core 3.0, it is found in the System.ObjectModel assembly.

Version introduced

3.0

This change only affects applications that use reflection to load the TypeDescriptionProviderAttribute type by calling a method such as Assembly.GetType or an overload of Activator.CreateInstance that assumes the type is in a particular assembly. If that is the case, the assembly referenced in the method call should be updated to reflect the type's new assembly location.

Category

Windows Forms

Affected APIs

  • None

Change in semantics of (string)null in Utf8JsonWriter

In .NET Core 3.0 Preview 7, the null string is treated as the empty string in Utf8JsonWriter. Starting with .NET Core 3.0 Preview 8, the null string throws an exception when used as a property name, and it emits the JSON null token when used as a value.

Change description

In .NET Core 3.0 Preview 7, the null string was treated as "" both when writing property names and when writing values.

Starting with .NET Core 3.0 Preview 8, a null property name throws an ArgumentNullException, and a null value is treated as a call to Utf8JsonWriter.WriteNull or Utf8JsonWriter.WriteNullValue().

Consider the following code:

string propertyName1 = null;
string propertyValue1 = null;
string propertyName2 = "prop2";
string propertyValue2 = null;
string simpleValue1 = null;

using (Utf8JsonWriter writer = new Utf8JsonWriter(stream))
{
    writer.WriteStartArray();

    writer.WriteStartObject();
    writer.WriteString(propertyName1, propertyValue1);
    writer.WriteString(propertyName2, propertyValue2);
    writer.WriteEndObject();

    writer.WriteStringValue(simpleValue1);

    writer.WriteEndArray();
}

If run with .NET Core 3.0 Preview 7, the writer produces the following output:

[{"":"","prop2":""},""]

Starting with .NET Core 3.0 Preview 8, the call to writer.WriteString(propertyName1, propertyValue1) throws an ArgumentNullException. If propertyName1 = null is replaced with propertyName1 = string.Empty, the output would now be:

[{"":null,"prop2":null},null]

This change was made to better align with caller expectations for null values.

Version introduced

3.0 Preview 8

When writing property names and values with the Utf8JsonWriter class:

  • Ensure non-null strings are used as property names.

  • If the previous behavior is desired, use a null coalescing invocation; for example, writer.WriteString(propertyName1 ?? "", propertyValue1).

  • If writing a null literal for a null string value is not desirable, use a null coalescing invocation; for example, writer.WriteString(propertyName2, propertyValue2 ?? "").

Category

CoreFx

Affected APIs


Json serializer exception type changed from JsonException to NotSupportedException

In .NET Core 3.0 Preview 6 through 8, the serializer would throw a JsonException when it encountered an unsupported derived collection type. Starting in .NET Core 3.0 Preview 9, the serializer throws a NotSupportedException instead.

Change description

In .NET Core 3.0 Preview 6 through Preview 8, the serializer would throw a JsonException when it encountered an unsupported derived collection type. An unsupported derived collection type is any collection type that isn't assignable to one of the following types:

Starting with .NET Core 3.0 Preview 9, the serializer throws a NotSupportedException When encountering an unsupported collection type. The new exception type better reflects why the deserialization operation is failing.

Version introduced

3.0 Preview 9

If you're catching JsonException when deserializing, you might want to consider also catching NotSupportedException.

Category

CoreFx

Affected APIs


JsonEncodedText.Encode methods have an additional JavaScriptEncoder argument

Starting with .NET Core 3.0 Preview 8, the JsonEncodedText.Encode methods contain an optional JavaScriptEncoder argument.

Change description

.NET Core 3.0 includes a new type, xref:System.Text.Json.JsonEncodedText.Encode%2A?displayProperty=nameWithType>. Starting with .NET Core 3.0 Preview 8, the signature of all JsonEncodedText.Encode method overloads has changed to include an optional JavaScriptEncoder parameter. This change was made to allow for a different or custom encoder.

The signature of the Encode methods in .NET Core 3.0 Preview 7 is:

namespace System.Text.Json
{
    public readonly struct JsonEncodedText
    {
        public static JsonEncodedText Encode(ReadOnlySpan<byte> utf8Value);
        public static JsonEncodedText Encode(ReadOnlySpan<char> value);
        public static JsonEncodedText Encode(string value);
    }
}

The signature of the same Encode methods in .NET Core 3.0 Preview 8 and later versions is:

namespace System.Text.Json
{
    public readonly struct JsonEncodedText
    {
        public static JsonEncodedText Encode(ReadOnlySpan<byte> utf8Value, JavaScriptEncoder encoder = null);
        public static JsonEncodedText Encode(ReadOnlySpan<char> value, JavaScriptEncoder encoder = null);
        public static JsonEncodedText Encode(string value, JavaScriptEncoder encoder = null);
    }
}

Version introduced

.NET Core 3.0 Preview 8

This is a binary breaking change only; a recompile against .NET Core 3.0 Preview 8 or a later version will fix any runtime issues.

Category

CoreFx

Affected APIs

JsonEncodedText.Encode(ReadOnlySpan<Byte>, JavaScriptEncoder) JsonEncodedText.Encode(ReadOnlySpan<Char>, JavaScriptEncoder) JsonEncodedText.Encode(String, JavaScriptEncoder)


JsonFactoryConverter.CreateConverter signature changed

To facilitate the composition of JsonConverterFactory classes, the CreateConverter method has been made public and given a second argument of type JsonSerializerOptions.

Change description

The signature of the CreateConverter method in .NET Core prior to version 3.0 Preview 8 was:

namespace System.Text.Json.Serialization
{
    public abstract class JsonConverterFactory : JsonConverter
    {
        protected abstract JsonConverter CreateConverter(Type typeToConvert);
    }
}

In .NET Core 3.0 Preview 8 and later versions, it is:

namespace System.Text.Json.Serialization
{
    public abstract class JsonConverterFactory : JsonConverter
    {
        public abstract JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options);
    }
}

Before this change, it was difficult to compose sealed factory converters, since there was no easy way to get the JsonConverter<T> from it. Making the factory method public and also passing the current JsonSerializerOptions allow for much more flexible composition.

Version introduced

3.0 Preview 8

Derived classes need to be updated and recompiled.

Affected APIs

JsonConverterFactory.CreateConverter(Type, JsonSerializerOptions).


ZipArchiveEntry no longer handles archives with inconsistent entry sizes

Zip archives list both compressed size and uncompressed size in the central directory and local header. The entry data itself also indicates its size. In .NET Core 2.2 and earlier versions, these values were never checked for consistency. Starting with .NET Core 3.0, they now are.

Change description

In .NET Core 2.2 and earlier versions, ZipArchiveEntry.Open() succeeds even if the local header disagrees with the central header of the zip file. Data is decompressed until the end of the compressed stream is reached, even if its length exceeds the uncompressed file size listed in the central directory/local header.

Starting with .NET Core 3.0, the ZipArchiveEntry.Open() method checks that local header and central header agree on compressed and uncompressed sizes of an entry. If they do not, the method throws an InvalidDataException if the archive's local header and/or data descriptor list sizes that disagree with the central directory of the zip file. When reading an entry, decompressed data is truncated to the uncompressed file size listed in the header.

This change was made to ensure that a ZipArchiveEntry correctly represents the size of its data and that only that amount of data is read.

Version introduced

3.0

Repackage any zip archive that exhibits these problems.

Category

CoreFx

Affected APIs


JsonElement API changes

Starting with .NET Core 3.0 Preview 7, some JsonElement APIs have changed to allow for easier discovery and greater usability.

Change description

In .NET Core 3.0 Preview 7, JsonElement APIs have changed as follows to allow for easier discovery and greater usability.

  1. All WriteProperty method overloads were removed from JsonElement. This affects code such as the following:

    using (JsonDocument doc = JsonDocument.Parse(jsonString))
    {
       JsonElement root = doc.RootElement;
       root.WriteProperty(propertyNameString, writer);
       // ..
       root.WriteProperty(propertyNameSpan, writer);
       // ..
       root.WriteProperty(propertyNameJsonEncoded, writer);
       // ..
       root.WriteProperty(utf8PropertyName, writer);
       //..
    }
    
  2. WriteValue was renamed as WriteTo. This affects code such as the following:

     using (JsonDocument doc = JsonDocument.Parse(jsonString))
     {
         JsonElement root = doc.RootElement;
         root.WriteValue(writer);
     }
    
  3. WriteTo now throws an ArgumentNullException when its method parameter is null.

Version introduced

3.0 Preview 7

If your code is affected by these changes, you can do the following:

  • There is no replacement API for the WriteProperty overloads in JsonElement. Instead, you can call one of the Utf8JsonWriter.WritePropertyName overloads along with the WriteTo method to achieve the same result. For example:

    using (JsonDocument doc = JsonDocument.Parse(jsonString))
    {
         JsonElement root = doc.RootElement;
         writer.WritePropertyName(propertyNameString);
         root.WriteTo(writer);
    }
    
  • Rename the WriteValue method to WriteTo(Utf8JsonWriter). The method parameter remains unchanged. For example, the previous code should be changed to the following:

    using (JsonDocument doc = JsonDocument.Parse(jsonString))
    {
         JsonElement root = doc.RootElement;
         root.WriteTo(writer);
    }
    
  • Handle the ArgumentNullException in calls to the WriteTo method.

Affected APIs

Cryptography

EnvelopedCms defaults to AES-256 encryption

The default symmetric encryption algorithm used by EnvelopedCms has changed from TripleDES to AES-256.

Change description

In .NET Core Preview 7 and earlier versions, when EnvelopedCms is used to encrypt data without specifying a symmetric encryption algorithm via a constructor overload, the data was encrypted with the TripleDES/3DES/3DEA/DES3-EDE algorithm.

Starting with .NET Core 3.0 Preview 8 (via version 4.6.0 of the System.Security.Cryptography.Pkcs NuGet package), the default algorithm has been changed to AES-256 for algorithm modernization and to improve the security of default options. If a message recipient certificate has a (non-EC) Diffie-Hellman public key, the encryption operation may fail with a CryptographicException due to limitations in the underlying platform.

In the following sample code, the data is encrypted with TripleDES if running on .NET Core 3.0 Preview 7 or earlier. If running on .NET Core 3.0 Preview 8 or later, it is encrypted with AES-256.

EnvelopedCms cms = new EnvelopedCms(content);
cms.Encrypt(recipient);
return cms.Encode();

Version introduced

3.0 Preview 8

If you are negatively impacted by the change, you can restore TripleDES encryption by explicitly specifying the encryption algorithm identifier in an EnvelopedCms constructor that includes a parameter of type AlgorithmIdentifier, such as:

Oid tripleDesOid = new Oid("1.2.840.113549.3.7", null);
AlgorithmIdentifier tripleDesIdentifier = new AlgorithmIdentifier(tripleDesOid);
EnvelopedCms cms = new EnvelopedCms(content, tripleDesIdentifier);

cms.Encrypt(recipient);
return cms.Encode()l

Category

Cryptography

Affected APIs


Minimum size for RSAOpenSsl key generation has increased

The minimum size for generating new RSA keys on Linux has increased from 384-bit to 512-bit.

Change description

Starting with .NET Core 3.0, the minimum legal key size reported by the LegalKeySizes property on RSA instances from RSA.Create, RSAOpenSsl.RSAOpenSsl, and RSACryptoServiceProvider.RSACryptoServiceProvider on Linux has increased from 384 to 512.

As a result, in .NET Core 2.2 and earlier versions, a method call such as RSA.Create(384) succeeds. In .NET Core 3.0 and later versions, the method call RSA.Create(384) throws an exception indicating the size is too small.

This change was made because OpenSSL, which performs the cryptographic operations on Linux, raised its minimum between versions 1.0.2 and 1.1.0. .NET Core 3.0 prefers OpenSSL 1.1.x to 1.0.x, and the minimum reported version was raised to reflect this new higher dependency limitation.

Version introduced

3.0

If you call any of the affected APIs, ensure that the size of any generated keys is not less than the provider minimum.

Note

384-bit RSA is already considered insecure (as is 512-bit RSA). Modern recommendations, such as NIST Special Publication 800-57 Part 1 Revision 4, suggest 2048-bit as the minimum size for newly generated keys.

Category

Cryptography

Affected APIs


.NET Core 3.0 prefers OpenSSL 1.1.x to OpenSSL 1.0.x

.NET Core for Linux, which works across multiple Linux distributions, can support both OpenSSL 1.0.x and OpenSSL 1.1.x. .NET Core 2.1 and .NET Core 2.2 look for 1.0.x first, then fall back to 1.1.x; .NET Core 3.0 looks for 1.1.x first. This change was made to add support for new cryptographic standards.

This change may impact libraries or applications that do platform interop with the OpenSSL-specific interop types in .NET Core.

Change description

In .NET Core 2.2 and earlier versions, the runtime prefers loading OpenSSL 1.0.x over 1.1.x. This means that the IntPtr and SafeHandle types for interop with OpenSSL are used with libcrypto.so.1.0.0 / libcrypto.so.1.0 / libcrypto.so.10 by preference.

Starting with .NET Core 3.0, the runtime prefers loading OpenSSL 1.1.x over OpenSSL 1.0.x, so the IntPtr and SafeHandle types for interop with OpenSSL are used with libcrypto.so.1.1 / libcrypto.so.11 / libcrypto.so.1.1.0 / libcrypto.so.1.1.1 by preference. As a result, libraries and applications that interoperate with OpenSSL directly may have incompatible pointers with the .NET Core-exposed values when upgrading from .NET Core 2.1 or .NET Core 2.2.

Version introduced

3.0

Libraries and applications that do direct operations with OpenSSL need to be careful to ensure they are using the same version of OpenSSL as the .NET Core runtime.

All libraries or applications that use IntPtr or SafeHandle values from the .NET Core cryptographic types directly with OpenSSL should compare the version of the library they use with the new SafeEvpPKeyHandle.OpenSslVersion property to ensure the pointers are compatible.

Category

Cryptography

Affected APIs


Better argument validation in the Pkcs8PrivateKeyInfo constructor

Starting with .NET Core 3.0 Preview 9, the Pkcs8PrivateKeyInfo constructor validates the algorithmParameters parameter as a single BER-encoded value.

Change description

Before .NET Core 3.0 Preview 9, the Pkcs8PrivateKeyInfo constructor did not validate the algorithmParameters argument. When this argument represented an invalid value, the constructor would succeed, but a call to any of the Encode(), TryEncode, Encrypt, or TryEncrypt methods would throw either an ArgumentException for an argument they did not accept (preEncodedValue) or a CryptographicException.

If run with .NET Core 3.0 before Preview 9, the following code throws an exception only when the Encode() method is called:

byte[] algorithmParameters = { 0x05, 0x00, 0x05, 0x00 };

var info = new Pkcs8PrivateKeyInfo(algorithmId, algorithmParameters, privateKey);
// This line throws an ArgumentException for `preEncodedValue`:
byte[] encoded = info.Encode();

Starting with .NET Core 3.0 Preview 9, the argument is validated in the constructor, and an invalid value results in the method throwing a CryptographicException. This change moves the exception closer to the source of the data error. For example:

byte[] algorithmParameters = { 0x05, 0x00, 0x05, 0x00 };

// This line throws a CryptographicException
var info = new Pkcs8PrivateKeyInfo(algorithmId, algorithmParameters, privateKey);

Version introduced

3.0 Preview 9

Ensure that only valid algorithmParameters values are provided, or that calls to the Pkcs8PrivateKeyInfo constructor test for both ArgumentException and CryptographicException if exception handling is desired.

Category

Cryptography

Affected APIs

Entity Framework Core

Entity Framework Core breaking changes

Globalization

"C" locale maps to the invariant locale

.NET Core 2.2 and earlier versions depend on the default ICU behavior, which maps the "C" locale to the en_US_POSIX locale. The en_US_POSIX locale has an undesirable collation behavior, because it doesn't support case-insensitive string comparisons. Because some Linux distributions set the "C" locale as the default locale, users were experiencing unexpected behavior.

Change description

Starting with .NET Core 3.0, the "C" locale mapping has changed to use the Invariant locale instead of en_US_POSIX. The "C" locale to Invariant mapping is also applied to Windows for consistency.

Mapping "C" to en_US_POSIX culture caused customer confusion, because en_US_POSIX doesn't support case insensitive sorting/searching string operations. Because the "C" locale is used as a default locale in some of the Linux distros, customers experienced this undesired behavior on these operating systems.

Version introduced

3.0

Nothing specific more than the awareness of this change. This change affects only applications that use the "C" locale mapping.

Category

Globalization

Affected APIs

All collation and culture APIs are affected by this change.

Networking

Default value of HttpRequestMessage.Version changed to 1.1

The default value of the System.Net.Http.HttpRequestMessage.Version property has changed from 2.0 to 1.1.

Version introduced

.NET Core 3.0

Change description

In .NET Core 1.0 through 2.0, the default value of the System.Net.Http.HttpRequestMessage.Version property is 1.1. Starting with .NET Core 2.1, it was changed to 2.1.

Starting with .NET Core 3.0, the default version number returned by the System.Net.Http.HttpRequestMessage.Version property is once again 1.1.

Update your code if it depends on the System.Net.Http.HttpRequestMessage.Version property returning a default value of 2.0.

Category

Networking

Affected APIs