.NET Core 3.0 中的中断性变更

若要迁移到 3.0 版 .NET Core、ASP.NET Core 或 EF Core,本文中列出的中断性变更可能会影响到你的应用。

ASP.NET Core

已删除过时防伪、CORS、诊断、MVC 和路由 API

删除了 ASP.NET Core 2.2 中的过时成员和兼容性开关。

引入的版本

3.0

更改原因

随着时间的推移,API 图面会得到改进。

针对 .NET Core 2.2 时,请遵循过时生成消息中的指导来改为采用新 API。

类别

ASP.NET Core

受影响的 API

以下类型和成员标记为对 ASP.NET Core 2.1 和 2.2 过时:

类型

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

构造函数

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

属性

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

方法


已删除“Pubternal”API

为了更好地维护 ASP.NET Core 面向公众的 API,*.Internal 命名空间中的大多数类型(称为 "pubternal" API)已成为真正的内部类型。 这些命名空间中的成员永远不会作为面向公众的 API 得到支持。 API 可能在次要版本中中断(这种情况经常会发生)。 在更新到 ASP.NET Core 3.0 时,依赖于这些 API 的代码会中断。

有关详细信息,请参阅 dotnet/aspnetcore#4932dotnet/aspnetcore#11312

引入的版本

3.0

旧行为

受影响的 API 使用 public 访问修饰符进行标记,并存在于 *.Internal 命名空间中。

新行为

受影响的 API 使用 internal 访问修饰符进行标记,不能再供该程序集外部的代码使用。

更改原因

对于这些 "pubternal" API,指导原则是:

  • 它们可能会更改,恕不另行通知。
  • 它们不遵从 .NET 策略来防止中断性变更。

保留这些 API public (即使保留在 *.Internal 命名空间中)会对客户造成混淆。

停止使用这些 "pubternal" API。 如果对其他 API 有任何疑问,请在 dotnet/aspnetcore 存储库中提问。

例如,请考虑 ASP.NET Core 2.2 项目中的以下 HTTP 请求缓冲代码。 EnableRewind 扩展方法存在于 Microsoft.AspNetCore.Http.Internal 命名空间中。

HttpContext.Request.EnableRewind();

在 ASP.NET Core 3.0 项目中,将 EnableRewind 调用替换为对 EnableBuffering 扩展方法的调用。 请求缓冲功能的工作方式与过去相同。 EnableBuffering 立即调用 internal API。

HttpContext.Request.EnableBuffering();

类别

ASP.NET Core

受影响的 API

名称中具有 Internal 段的 Microsoft.AspNetCore.*Microsoft.Extensions.* 命名空间中的所有 API。 例如:

  • Microsoft.AspNetCore.Authentication.Internal
  • Microsoft.AspNetCore.Builder.Internal
  • Microsoft.AspNetCore.DataProtection.Cng.Internal
  • Microsoft.AspNetCore.DataProtection.Internal
  • Microsoft.AspNetCore.Hosting.Internal
  • Microsoft.AspNetCore.Http.Internal
  • Microsoft.AspNetCore.Mvc.Core.Infrastructure
  • Microsoft.AspNetCore.Mvc.Core.Internal
  • 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
  • Microsoft.AspNetCore.Rewrite.Internal
  • Microsoft.AspNetCore.Routing.Internal
  • Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal
  • Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
  • Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
  • Microsoft.AspNetCore.Server.Kestrel.Https.Internal

身份验证:Google+ 已弃用并被替换

Google 早在 2019 年 1 月 28 日就开始关闭对应用使用 Google + 登录。

更改描述

ASP.NET 4.x 和 ASP.NET Core 已使用 Google + 登录 API 在 Web 应用中对 Google 帐户用户进行身份验证。 受影响的 NuGet 包为 Microsoft.AspNetCore.Authentication.Google(对于 ASP.NET Core)和 Microsoft.Owin.Security.Google(对于具有 ASP.NET Web Forms 和 MVC 的 Microsoft.Owin)。

Google 的替代 API 使用不同的数据源和格式。 下面提供的缓解措施和解决方案说明存在结构性更改。 应用应验证数据本身是否仍然满足其需求。 例如,名称、电子邮件地址、配置文件链接和个人资料照片的值可能与以前稍有不同。

引入的版本

所有版本。 此更改是 ASP.NET Core 的外部更改。

包含 ASP.NET Web Forms 和 MVC 的 Owin

针对 Microsoft.Owin 3.1.0 和更高版本,本文概述了临时的缓解措施。 应用应通过缓解措施来完成测试,以检查数据格式的更改。 计划发布 Microsoft.Owin 4.0.1,并提供一个修补程序。 使用任何较低版本的应用都应更新到版本 4.0.1。

ASP.NET Core 1.x

包含 ASP.NET Web Form 和MVC 的 Owin的缓解措施可应用于 ASP.NET Core 1.x。 未计划 NuGet 包修补程序,因为 1.x 已处于生命周期结束状态。

ASP.NET Core 2.x

对于 Microsoft.AspNetCore.Authentication.Google 版本 2.x,请将对 Startup.ConfigureServicesAddGoogle 的现有调用替换为以下代码:

.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");
});

2 月 2.1 和 2.2 修补程序将前面的重新配置合并为新的默认配置。 不会为 ASP.NET Core 2.0 计划任何修补程序,因为它的生命周期已经结束

ASP.NET Core 3.0

为 ASP.NET Core 2.x 提供的缓解措施也可用于 ASP.NET Core 3.0。 未来的 3.0 预览版中,可能会删除 Microsoft.AspNetCore.Authentication.Google 包。 改为将用户定向到 Microsoft.AspNetCore.Authentication.OpenIdConnect。 以下代码演示了如何在 Startup.ConfigureServices 中将 AddGoogle 替换为 AddOpenIdConnect。 此替换可以用于 ASP.NET Core 2.0 及更高版本,并且可以根据需要应用于 ASP.NET Core 1.x。

.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 "/signin-oidc"
    o.Scope.Add("email");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

类别

ASP.NET Core

受影响的 API

Microsoft.AspNetCore.Authentication.Google


身份验证:已删除 HttpContext.Authentication 属性

已删除 HttpContext 上弃用的 Authentication 属性。

更改描述

作为 dotnet/aspnetcore#6504 的一部分,已删除 HttpContext 上弃用的 Authentication 属性。 从 2.0 开始,Authentication 属性已弃用。 迁移指南 已发布,可使用此弃用属性将代码迁移到新的替换 API。 在 commit dotnet/aspnetcore@d7a7c65 中移除了与旧 ASP.NET Core 1.x 身份验证堆栈相关的其余未使用的类/API。

有关讨论,请参阅 dotnet/aspnetcore#6533

引入的版本

3.0

更改原因

ASP.NET Core 1.0 API 已被 Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions 中的扩展方法替换。

请参阅迁移指南

类别

ASP.NET Core

受影响的 API


身份验证:Newtonsoft.json 类型已替换

在 ASP.NET Core 3.0 中,身份验证 API 中使用的 Newtonsoft.Json 类型已替换为 System.Text.Json 类型。 除以下情况外,身份验证包的基本使用不受影响:

  • 派生自 OAuth 提供程序的类,例如来自 aspnet-contrib 的类。
  • 高级声明操作实现。

有关详细信息,请参阅 dotnet/aspnetcore#7105。 有关讨论,请参阅 dotnet/aspnetcore#7289

引入的版本

3.0

对于派生的 OAuth 实现,最常见的更改是将 JObject.Parse 替换为 CreateTicketAsync 重写中的 JsonDocument.Parse,如本文所示。 JsonDocument 可实现 IDisposable

以下列表概述了已知更改:

类别

ASP.NET Core

受影响的 API


身份验证:已更改 OAuthHandler ExchangeCodeAsync 签名

在 ASP.NET Core 3.0 中,OAuthHandler.ExchangeCodeAsync 的签名已从以下位置更改:

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

到:

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

引入的版本

3.0

旧行为

coderedirectUri 字符串作为单独的参数传递。

新行为

CodeRedirectUriOAuthCodeExchangeContext 上的属性,可通过 OAuthCodeExchangeContext 构造函数进行设置。 新的 OAuthCodeExchangeContext 类型是传递到 OAuthHandler.ExchangeCodeAsync 的唯一参数。

更改原因

此更改允许以非中断方式提供其他参数。 无需创建新的 ExchangeCodeAsync 重载。

使用适当的 coderedirectUri 值构造 OAuthCodeExchangeContext。 必须提供 AuthenticationProperties 实例。 此单个 OAuthCodeExchangeContext 实例可传递到 OAuthHandler.ExchangeCodeAsync 而不是多个参数。

类别

ASP.NET Core

受影响的 API

OAuthHandler<TOptions>.ExchangeCodeAsync(String, String)


授权:AddAuthorization 重载已移到不同的程序集

用于驻留在 Microsoft.AspNetCore.Authorization 中的核心 AddAuthorization 方法已重命名为 AddAuthorizationCore。 旧的 AddAuthorization 方法仍然存在,但却在 Microsoft.AspNetCore.Authorization.Policy 程序集中。 使用这两种方法的应用应该不会受到任何影响。 请注意,Microsoft.AspNetCore.Authorization.Policy 现随附于共享框架而不是独立的包中,如共享框架:从 Microsoft.AspNetCore.App 中删除了程序集中所述。

引入的版本

3.0

旧行为

Microsoft.AspNetCore.Authorization 中已存在 AddAuthorization 方法。

新行为

Microsoft.AspNetCore.Authorization.Policy 中存在 AddAuthorization 方法。 AddAuthorizationCore 是旧方法的新名称。

更改原因

AddAuthorization 是一个更好的方法名称,用于添加授权所需的所有常用服务。

添加对 Microsoft.AspNetCore.Authorization.Policy 的引用或改用 AddAuthorizationCore

类别

ASP.NET Core

受影响的 API

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


授权:已从 AuthorizationFilterContext.Filters 中删除 IAllowAnonymous

从 ASP.NET Core 3.0 起,MVC 不会为在控制器和操作方法上发现的 [AllowAnonymous] 属性添加 AllowAnonymousFilters。 此更改针对 AuthorizeAttribute 派生在本地进行处理,但对于 IAsyncAuthorizationFilterIAuthorizationFilter 实现来说是一个重大变更。 包装在 [TypeFilter] 属性中的此类实现是在需要配置和依赖项注入时实现强类型的基于属性的授权的常见的支持方式。

引入的版本

3.0

旧行为

IAllowAnonymous 出现在 AuthorizationFilterContext.Filters 集合中。 对接口的状态进行测试是对单个控制器方法上的筛选器进行重写或禁用的一种有效方法。

新行为

IAllowAnonymous 不再出现在 AuthorizationFilterContext.Filters 集合中。 依赖于旧行为的 IAsyncAuthorizationFilter 实现通常导致间歇性 HTTP 401 未授权或 HTTP 403 禁止响应。

更改原因

ASP.NET Core 3.0 中引入了新的终结点路由策略。

在终结点元数据中搜索 IAllowAnonymous。 例如:

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

此 HasAllowAnonymous 方法中演示了此方法。

类别

ASP.NET Core

受影响的 API


授权:IAuthorizationPolicyProvider 实现需要新方法

在 ASP.NET Core 3.0 中,已将一个新 GetFallbackPolicyAsync 方法添加到 IAuthorizationPolicyProvider。 当未指定策略时,授权中间件会使用此回退策略。

有关详细信息,请参阅 dotnet/aspnetcore#9759

引入的版本

3.0

旧行为

IAuthorizationPolicyProvider 的实现不需要 GetFallbackPolicyAsync 方法。

新行为

IAuthorizationPolicyProvider 的实现需要 GetFallbackPolicyAsync 方法。

更改原因

如果未指定策略,则新 AuthorizationMiddleware 需要使用新方法。

GetFallbackPolicyAsync 方法添加到 IAuthorizationPolicyProvider 的实现。

类别

ASP.NET Core

受影响的 API

Microsoft.AspNetCore.Authorization.IAuthorizationPolicyProvider


缓存:已删除 CompactOnMemoryPressure 属性

ASP.NET Core 3.0 版本已删除过时的 MemoryCacheOptions API

更改描述

此更改是对 aspnet/Caching#221 的后续补充。 有关讨论,请参阅 dotnet/extensions#1062

引入的版本

3.0

旧行为

MemoryCacheOptions.CompactOnMemoryPressure 属性可用。

新行为

MemoryCacheOptions.CompactOnMemoryPressure 属性已被删除。

更改原因

自动压缩缓存会引起问题。 若要避免意外行为,只应在需要时压缩缓存。

若要压缩缓存,请向下转换到 MemoryCache 并在需要时调用 Compact

类别

ASP.NET Core

受影响的 API

MemoryCacheOptions.CompactOnMemoryPressure


缓存:Microsoft.Extensions.Caching.SqlServer 使用新的 SqlClient 包

Microsoft.Extensions.Caching.SqlServer 包将使用新的 Microsoft.Data.SqlClient 包,而不是 System.Data.SqlClient 包。 此更改可能会导致轻微的行为中断性变更。 有关详细信息,请参阅引入新的 Microsoft.Data.SqlClient

引入的版本

3.0

旧行为

Microsoft.Extensions.Caching.SqlServer 包已使用过 System.Data.SqlClient 包。

新行为

Microsoft.Extensions.Caching.SqlServer 现在使用 Microsoft.Data.SqlClient 包。

更改原因

Microsoft.Data.SqlClient 是从 System.Data.SqlClient 生成的新包。 从现在开始,所有新功能的工作都在该包中进行。

客户无需担心此中断性变更,除非他们使用 Microsoft.Extensions.Caching.SqlServer 包返回的类型,并将它们强制转换为 System.Data.SqlClient 类型。 例如,如果有人将 DbConnection 强制转换为旧的 SqlConnection 类型,则需要将转换更改为新的 Microsoft.Data.SqlClient.SqlConnection 类型。

类别

ASP.NET Core

受影响的 API


缓存:ResponseCaching“Pubternal”类型已更改为内部类型

在 ASP.NET Core 3.0 中,ResponseCaching 中的“pubternal”类型已更改为 internal

此外,IResponseCachingPolicyProviderIResponseCachingKeyProvider 的默认实现不再作为 AddResponseCaching 方法的一部分添加到服务。

更改描述

在 ASP.NET Core 中,“pubternal”类型声明为 public,但驻留在后缀为 .Internal 的命名空间中。 尽管这些类型为 public,但它们没有支持策略,可能会发生中断性变更。 遗憾的是,经常会意外使用这些类型,导致对这些项目做出中断性变更,并使维护框架的能力受到限制。

引入的版本

3.0

旧行为

这些类型公开可见,但不受支持。

新行为

这些类型现在为 internal

更改原因

internal 范围更好地反映了不受支持的策略。

复制应用或库使用的类型。

类别

ASP.NET Core

受影响的 API


数据保护:DataProtection.Blobs 使用新的 Azure 存储 API

Azure.Extensions.AspNetCore.DataProtection.Blobs 取决于 Azure 存储库。 这些库已重命名其程序集、包和命名空间。 从 ASP.NET Core 3.0 开始,Azure.Extensions.AspNetCore.DataProtection.Blobs 使用新的带有 Azure.Storage. 前缀的 API 和包。

有关 Azure 存储 API 的问题,请使用 https://github.com/Azure/azure-storage-net。 有关此问题的讨论,请参阅 dotnet/aspnetcore#19570

引入的版本

3.0

旧行为

该包引用了 WindowsAzure.Storage NuGet 包。 该包引用 Microsoft.Azure.Storage.Blob NuGet 包。

新行为

该包引用 Azure.Storage.Blob NuGet 包。

更改原因

此更改允许 Azure.Extensions.AspNetCore.DataProtection.Blobs 迁移到建议的 Azure 存储包。

如果仍需要将较旧的 Azure 存储 API 与 ASP.NET Core 3.0 一起使用,请将直接依赖项添加到包 WindowsAzure.StorageMicrosoft.Azure.Storage。 此包可以与新的 Azure.Storage API 一起安装。

在许多情况下,升级仅涉及更改 using 语句以使用新的命名空间:

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

类别

ASP.NET Core

受影响的 API


托管:已从 Windows 托管捆绑包中删除 AspNetCoreModule V1

从 ASP.NET Core 3.0 开始,Windows 托管捆绑不包含 AspNetCoreModule (ANCM) V1。

ANCM V2 向后兼容 ANCM OutOfProcess,建议与 ASP.NET Core 3.0 应用一起使用。

有关讨论,请参阅 dotnet/aspnetcore#7095

引入的版本

3.0

旧行为

ANCM V1 包含在 Windows 托管捆绑包中。

新行为

ANCM V1 不包含在 Windows 托管捆绑包中。

更改原因

ANCM V2 向后兼容 ANCM OutOfProcess,建议与 ASP.NET Core 3.0 应用一起使用。

将 ANCM V2 与 ASP.NET Core 3.0 应用一起使用。

如果需要 ANCM V1,则可以使用 ASP.NET Core 2.1 或 2.2 Windows 托管捆绑包进行安装。

此更改将中断以下 ASP.NET Core 3.0 应用:

  • 已明确选择将 ANCM V1 与 <AspNetCoreModuleName>AspNetCoreModule</AspNetCoreModuleName> 结合使用。
  • 具有 <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" /> 的自定义 web.config 文件。

类别

ASP.NET Core

受影响的 API


托管:通用主机限制 Startup 构造函数注入

通用主机支持的 Startup 类构造函数注入的唯一类型为 IHostEnvironmentIWebHostEnvironmentIConfiguration。 使用 WebHost 的应用不受影响。

更改描述

在低于 ASP.NET Core 3.0 的版本中,构造函数注入可用于 Startup 类的构造函数中的任意类型。 在 ASP.NET Core 3.0 中,Web 堆栈将重新平台化到通用主机库上。 可以在模板的 Program .cs 文件中查看更改:

ASP.NET Core 2.x:

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

ASP.NET Core 3.0:

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

Host 使用一个依赖关系注入 (DI) 容器生成应用。 WebHost 使用两个容器:一个用于主机,另一个用于应用。 因此,Startup 构造函数不再支持自定义服务注入。 只能注入 IHostEnvironmentIWebHostEnvironmentIConfiguration。 此更改可防止出现 DI 问题,例如重复创建单一实例服务。

引入的版本

3.0

更改原因

此更改是将 Web 堆栈重新平台化到通用主机库的结果。

将服务注入 Startup.Configure 方法签名。 例如:

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

类别

ASP.NET Core

受影响的 API


托管:已为 IIS 进程外应用启用 HTTPS 重定向

用于通过 IIS 进程外应用进行托管的 ASP.NET Core 模块 (ANCM) 的 13.0.19218.0 版本可为 ASP.NET Core 3.0 和 2.2 应用启用现有 HTTPS 重定向功能。

有关讨论,请参阅 dotnet/AspNetCore#15243

引入的版本

3.0

旧行为

ASP.NET Core 2.1 项目模板首先引入了对 HTTPS 中间件方法的支持,例如 UseHttpsRedirectionUseHsts。 启用 HTTPS 重定向需要添加配置,因为开发中的应用不使用默认端口 443。 仅当请求已使用 HTTPS 时,HTTP 严格传输安全 (HSTS) 才处于活动状态。 默认跳过 localhost。

新行为

在 ASP.NET Core 3.0 中,IIS HTTPS 方案已增强。 利用此增强功能,应用可以发现服务器的 HTTPS 端口并默认使 UseHttpsRedirection 工作。 进程内组件通过 IServerAddresses 功能完成端口发现,该功能仅影响 ASP.NET Core 3.0 应用,因为进程内库通过框架进行版本控制。 进程外组件已更改为自动添加 ASPNETCORE_HTTPS_PORT 环境变量。 由于进程外组件是全局共享组件,因此此更改会同时影响 ASP.NET Core 2.2 和 3.0 应用。 ASP.NET Core 2.1 应用不会受到影响,因为它们默认使用 ANCM 的先前版本。

前面的行为已在 ASP.NET Core 3.0.1 和 3.1.0 预览版 3 中进行修改,以反转 ASP.NET Core 2.x 中的行为更改。 这些更改仅影响 IIS 进程外应用。

如上所述,安装 ASP.NET Core 3.0.0 还具有在 ASP.NET Core 2.x 应用中激活 UseHttpsRedirection 中间件的副作用。 已对 ASP.NET Core 3.0.1 和 3.1.0 预览版 3 中的 ANCM 进行更改,以确保安装它们时不会再对 ASP.NET Core 2.x 应用产生此影响。 ANCM 在 ASP.NET Core 3.0.0 中填充的 ASPNETCORE_HTTPS_PORT 环境变量在 ASP.NET Core 3.0.1 和 3.1.0 预览版 3 中已更改为 ASPNETCORE_ANCM_HTTPS_PORTUseHttpsRedirection 在这些版本中也已更新,可同时理解新旧变量。 不会更新 ASP.NET Core 2.x。 因此,它会还原为默认禁用的先前行为。

更改原因

已改进 ASP.NET Core 3.0 功能。

如果希望所有客户端都使用 HTTPS,则无需执行任何操作。 要允许部分客户端使用 HTTP,请执行以下步骤之一:

  • 从项目的 Startup.Configure 方法中删除对 UseHttpsRedirectionUseHsts 的调用,然后重新部署应用。

  • 在 web.config 文件中,将 ASPNETCORE_HTTPS_PORT 环境变量设置为空字符串。 无需重新部署应用即可直接在服务器上进行此更改。 例如:

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

UseHttpsRedirection 仍可:

  • 在 ASP.NET Core 2.x 中手动激活,方法是将 ASPNETCORE_HTTPS_PORT 环境变量设置为相应的端口号(在大多数生产方案中为 443)。
  • 在 ASP.NET Core 3.x 中停用,方法是使用空字符串值定义 ASPNETCORE_ANCM_HTTPS_PORT。 此值的设置方式与前面的 ASPNETCORE_HTTPS_PORT 示例相同。

运行 ASP.NET Core 3.0.0 应用的计算机应先安装 ASP.NET Core 3.0.1 运行时,然后再安装 ASP.NET Core 3.1.0 预览版 3 ANCM。 这样做可以确保继续按预期对 ASP.NET Core 3.0 应用运行 UseHttpsRedirection

在 Azure 应用服务中,由于 ANCM 具有全局性,其部署时间与运行时不同。 部署 ASP.NET Core 3.0.1 和 3.1.0 后,才会将 ANCM 以及相应的更改部署到 Azure。

类别

ASP.NET Core

受影响的 API

HttpsPolicyBuilderExtensions.UseHttpsRedirection(IApplicationBuilder)


托管:IHostingEnvironment 和 IApplicationLifetime 类型已标记为过时并被替换

引入了新类型以替换现有的 IHostingEnvironmentIApplicationLifetime 类型。

引入的版本

3.0

旧行为

Microsoft.Extensions.HostingMicrosoft.AspNetCore.Hosting 有两个不同的 IHostingEnvironmentIApplicationLifetime 类型。

新行为

旧类型已标记为过时,并已替换为新类型。

更改原因

在 ASP.NET Core 2.1 中引入 Microsoft.Extensions.Hosting 时,从 Microsoft.AspNetCore.Hosting 复制了某些类型(如 IHostingEnvironmentIApplicationLifetime)。 某些 ASP.NET Core 3.0 更改会导致应用包括 Microsoft.Extensions.HostingMicrosoft.AspNetCore.Hosting 命名空间。 如果同时引用了两个命名空间,则使用这些重复类型会导致“引用不明确”编译器错误。

将旧类型的所有使用替换为新引入的类型,如下所示:

过时类型(警告):

新类型:

新的 IHostEnvironmentIsDevelopmentIsProduction 扩展方法在 Microsoft.Extensions.Hosting 命名空间中。 可能需要将该命名空间添加到项目中。

类别

ASP.NET Core

受影响的 API


托管:已从 WebHostBuilder 依赖项中删除 ObjectPoolProvider

作为使 ASP.NET Core 更具成本效益计划的一部分,ObjectPoolProvider 已从主要依赖项集中删除。 依赖于 ObjectPoolProvider 的特定组件现在会自行添加。

有关讨论,请参阅 dotnet/aspnetcore#5944

引入的版本

3.0

旧行为

WebHostBuilder 默认在 DI 容器中提供 ObjectPoolProvider

新行为

WebHostBuilder 默认不再在 DI 容器中提供 ObjectPoolProvider

更改原因

进行此更改是为了使 ASP.NET Core 更具成本效益。

如果组件需要 ObjectPoolProvider,则需要通过 IServiceCollection 将其添加到依赖项。

类别

ASP.NET Core

受影响的 API


HTTP:已删除 DefaultHttpContext 扩展性

作为 ASP.NET Core 3.0 性能改进的一部分,已删除 DefaultHttpContext 的扩展性。 此类现在为 sealed。 有关详细信息,请参阅 dotnet/aspnetcore#6504

如果单元测试使用 Mock<DefaultHttpContext>,请改用 Mock<HttpContext>new DefaultHttpContext()

有关讨论,请参阅 dotnet/aspnetcore#6534

引入的版本

3.0

旧行为

类可从 DefaultHttpContext 派生。

新行为

类不可从 DefaultHttpContext 派生。

更改原因

最初提供扩展性是为了允许 HttpContext 合并,但它引入了不必要的复杂性并妨碍了其他优化。

如果在单元测试中使用 Mock<DefaultHttpContext>,请改为开始使用 Mock<HttpContext>

类别

ASP.NET Core

受影响的 API

Microsoft.AspNetCore.Http.DefaultHttpContext


HTTP:HeaderNames 常量已更改为静态只读

从 ASP.NET Core 3.0 预览版 5 开始,Microsoft.Net.Http.Headers.HeaderNames 中的字段已从 const 更改为 static readonly

有关讨论,请参阅 dotnet/aspnetcore#9514

引入的版本

3.0

旧行为

这些字段以前是 const

新行为

这些字段现在是 static readonly

更改原因

更改:

  • 防止将值嵌入到程序集边界内,允许根据需要更正值。
  • 实现更快的引用同等性检查。

针对 3.0 重新编译。 通过以下方式使用这些字段的源代码将无法再执行此项操作:

  • 作为特性参数
  • 作为 switch 语句中的 case
  • 定义其他 const

若要解决中断性变更,请切换到使用自定义标头名称常量或字符串文本。

类别

ASP.NET Core

受影响的 API

Microsoft.Net.Http.Headers.HeaderNames


HTTP:响应正文基础结构更改

支持 HTTP 响应正文的基础结构已发生更改。 如果直接使用 HttpResponse,则不需要进行任何代码更改。 如果要包装或替换 HttpResponse.Body 或访问 HttpContext.Features,请进行进一步了解。

引入的版本

3.0

旧行为

有三个 API 与 HTTP 响应正文关联:

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

新行为

如果替换 HttpResponse.Body,则它通过使用 StreamResponseBodyFeature 为所有预期的 API 提供默认实现,将整个 IHttpResponseBodyFeature 替换为给定流周围的包装器。 重新设置回原始流会还原此更改。

更改原因

动机是将响应正文 API 合并为单一新功能接口。

使用之前在其中使用 IHttpResponseFeature.BodyIHttpSendFileFeatureIHttpBufferingFeatureIHttpResponseBodyFeature

类别

ASP.NET Core

受影响的 API


SameSite 是 cookie 的一个选项,可以帮助减轻某些跨站点请求伪造 (CSRF) 攻击。 最初引入此选项时,各种 ASP.NET Core API 中使用了不一致的默认值。 不一致会导致结果混乱。 从 ASP.NET Core 3.0 开始,这些默认值更一致了。 必须为每个组件选择启用此功能。

引入的版本

3.0

旧行为

类似的 ASP.NET Core API 使用不同的默认值 SameSiteMode。 在 HttpResponse.Cookies.Append(String, String)HttpResponse.Cookies.Append(String, String, CookieOptions) 中可以看到不一致的示例,它们分别默认为 SameSiteMode.NoneSameSiteMode.Lax

新行为

所有受影响的 API 都默认为 SameSiteMode.None

更改原因

更改了默认值,使 SameSite 成为可选功能。

发出 cookie 的每个组件都需要决定 SameSite 是否适用于其方案。 检查受影响 API 的使用情况,并根据需要重新配置 SameSite

类别

ASP.NET Core

受影响的 API


HTTP:所有服务器均禁用同步 IO

从 ASP.NET Core 3.0 开始,默认将禁用同步服务器操作。

更改描述

AllowSynchronousIO 是每台服务器中包含的一个选项,用于启用或禁用同步 IO API,如 HttpRequest.Body.ReadHttpResponse.Body.WriteStream.Flush。 这些 API 长期以来一直是线程不足和应用挂起的根源。 从 ASP.NET Core 3.0 预览版 3 开始,默认将禁用这些同步操作。

受影响的服务器:

  • Kestrel
  • HttpSys
  • IIS(进程内)
  • TestServer

错误应如下所示:

  • 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.

每台服务器都有一个 AllowSynchronousIO 选项,该选项控制此行为,且它们的默认值当前为 false

作为一种临时缓解措施,还可以根据每个请求重写该行为。 例如:

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

如果调用 Dispose 中同步 API 的 TextWriter 或另一个流出现问题,请改为调用新的 DisposeAsync API。

有关讨论,请参阅 dotnet/aspnetcore#7644

引入的版本

3.0

旧行为

默认情况下允许 HttpRequest.Body.ReadHttpResponse.Body.WriteStream.Flush

新行为

默认情况下,不允许使用这些同步 API:

错误应如下所示:

  • 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.

更改原因

这些同步 API 长期以来一直是线程不足和应用挂起的根源。 从 ASP.NET Core 3.0 预览版 3 开始,默认将禁用同步操作。

使用这些方法的异步版本。 作为一种临时缓解措施,还可以根据每个请求重写该行为。

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

类别

ASP.NET Core

受影响的 API


标识:已删除 AddDefaultUI 方法重载

从 ASP.NET Core 3.0 开始,IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder,UIFramework) 方法重载不再存在。

引入的版本

3.0

更改原因

此更改是采用静态 Web 资产功能的结果。

调用 IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder) 而不是使用两个参数的重载。 如果使用的是 Bootstrap 3,还应将以下行添加到项目文件中的 <PropertyGroup> 元素:

<IdentityUIFrameworkVersion>Bootstrap3</IdentityUIFrameworkVersion>

类别

ASP.NET Core

受影响的 API

IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder,UIFramework)


标识:已更改 UI 的默认 Bootstrap 版本

从 ASP.NET Core 3.0 开始,标识 UI 默认为使用 Bootstrap 版本 4。

引入的版本

3.0

旧行为

services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(); 方法调用以前与 services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(UIFramework.Bootstrap3); 相同

新行为

services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(); 方法调用现在与 services.AddDefaultIdentity<IdentityUser>().AddDefaultUI(UIFramework.Bootstrap4); 相同

更改原因

在 ASP.NET Core 3.0 时间范围内发布了 Bootstrap 4。

如果使用默认标识用户界面并将其添加到 Startup.ConfigureServices 中,则会受到此更改的影响,如以下示例中所示:

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

请执行以下一项操作:

  • 迁移应用,以使用其迁移指南来使用 Bootstrap 4。

  • 更新 Startup.ConfigureServices 以强制使用 Bootstrap 3。 例如:

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

类别

ASP.NET Core

受影响的 API


标识:对于未经身份验证的标识,SignInAsync 会引发异常

默认情况下,SignInAsync 会为其中 IsAuthenticatedfalse 的主体/标识引发异常。

引入的版本

3.0

旧行为

SignInAsync 接受任何主体/标识,包括其中 IsAuthenticatedfalse 的标识。

新行为

默认情况下,SignInAsync 会为其中 IsAuthenticatedfalse 的主体/标识引发异常。 有一个新的标志可禁止显示此行为,但默认行为已更改。

更改原因

旧行为是有问题的,因为在默认情况下,[Authorize] / RequireAuthenticatedUser() 拒绝了这些主体。

在 ASP.NET Core 3.0 预览版 6 中,AuthenticationOptions 上有 RequireAuthenticatedSignIn 标记,默认为 true。 将此标志设置为 false 以还原旧行为。

类别

ASP.NET Core

受影响的 API


标识:SignInManager 构造函数接受新参数

从 ASP.NET Core 3.0 开始,新的 IUserConfirmation<TUser> 参数添加到了 SignInManager 构造函数中。 有关详细信息,请参阅 dotnet/aspnetcore#8356

引入的版本

3.0

更改原因

更改的动机是为了添加对标识中的新电子邮件/确认流的支持。

如果手动构造 SignInManager,请提供 IUserConfirmation 的实现,或从依赖项注入获取一个实现来提供。

类别

ASP.NET Core

受影响的 API

SignInManager<TUser>


标识:UI 使用静态 Web 资产功能

ASP.NET Core 3.0 引入了静态 Web 资产功能,标识 UI 已采用此功能。

更改描述

由于标识 UI 采用静态 Web 资产功能,因此:

  • 可通过使用项目文件中的 IdentityUIFrameworkVersion 属性来完成框架选择。
  • Bootstrap 4 是标识 UI 的默认 UI 框架。 Bootstrap 3 的生命周期已经结束,应考虑迁移到受支持的版本。

引入的版本

3.0

旧行为

标识 UI 的默认 UI 框架为 Bootstrap 3。 可使用 Startup.ConfigureServicesAddDefaultUI 方法调用的参数配置 UI 框架。

新行为

标识 UI 的默认 UI 框架为 Bootstrap 4。 UI 框架必须在项目文件中进行配置,而不是在 AddDefaultUI 方法调用中配置。

更改原因

采用静态 Web 资产功能要求 UI 框架配置迁移到 MSBuild。 要在哪个框架上进行嵌入的决策是生成时决策,而非运行时决策。

查看站点 UI,以确保新的 Bootstrap 4 组件兼容。 如有必要,请使用 IdentityUIFrameworkVersion MSBuild 属性还原为 Bootstrap 3。 将属性添加到项目文件中的 <PropertyGroup> 元素:

<IdentityUIFrameworkVersion>Bootstrap3</IdentityUIFrameworkVersion>

类别

ASP.NET Core

受影响的 API

IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder, UIFramework)


Kestrel:已删除连接适配器

作为将“pubternal”API 移动到 public 的移动的一部分,已从 Kestrel 中删除 IConnectionAdapter 的概念。 正在将连接适配器替换为连接中间件(这与 ASP.NET Core 管道中的 HTTP 中间件类似,但适用于较低级别的连接)。 HTTPS 和连接日志记录已从连接适配器转移到连接中间件。 这些扩展方法应能继续无缝运行,但实现详细信息发生了改变。

有关详细信息,请参阅 dotnet/aspnetcore#11412。 有关讨论,请参阅 dotnet/aspnetcore#11475

引入的版本

3.0

旧行为

Kestrel 扩展性组件是使用 IConnectionAdapter 创建的。

新行为

Kestrel 扩展性组件被创建为中间件

更改原因

此更改旨在提供更灵活的扩展性体系结构。

转换 IConnectionAdapter 的任何实现以使用新的中间件模式,如此处所示。

类别

ASP.NET Core

受影响的 API

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


Kestrel:已删除空 HTTPS 程序集

已删除程序集 Microsoft.AspNetCore.Server.Kestrel.Https

引入的版本

3.0

更改原因

在 ASP.NET Core 2.1 中,Microsoft.AspNetCore.Server.Kestrel.Https 的内容已移动到 Microsoft.AspNetCore.Server.Kestrel.Core 中。 此更改是使用 [TypeForwardedTo] 属性以非中断方式进行的。

  • 引用 Microsoft.AspNetCore.Server.Kestrel.Https 2.0 的库应将所有 ASP.NET Core 依赖项更新为 2.1 或更高版本。 否则,它们可能会在加载到 ASP.NET Core 3.0 应用时中断。
  • 面向 ASP.NET Core 2.1 和更高版本的应用和库应删除对 Microsoft.AspNetCore.Server.Kestrel.Https NuGet 包的任何直接引用。

类别

ASP.NET Core

受影响的 API


Kestrel:请求尾部标头已移到新集合

在以前的版本中,当读取请求正文直到结尾时,Kestrel 会将 HTTP/1.1 分块尾部标头添加到请求标头集合中。 此行为将引发对标头和尾部之间存在不明确性的担忧。 因此,做出了将尾部移动到新集合的决定。

HTTP/2 请求尾部在 ASP.NET Core 2.2 中不可用,但现在可用于 ASP.NET Core 3.0 的此新集合。

添加了新的请求扩展方法以访问这些尾部。

读取整个请求正文后,HTTP/1.1 尾部即可用。

从客户端收到 HTTP/2 尾部后,这些尾部即可用。 客户端将不会发生尾部,直到整个请求正文至少已由服务器缓冲。 可能需要读取请求正文,以释放缓冲区空间。 如果读取请求正文直到结尾,则尾部始终可用。 尾部标记正文的结尾。

引入的版本

3.0

旧行为

请求尾部标头将添加到 HttpRequest.Headers 集合中。

新行为

请求尾部标头在 HttpRequest.Headers 集合中不存在。 在 HttpRequest 上使用以下扩展方法来访问它们:

  • GetDeclaredTrailers() - 获取列出了正文后应具有的尾部的请求“尾部”标头。
  • SupportsTrailers() - 指示请求是否支持接收尾部标头。
  • CheckTrailersAvailable() - 确定请求是否支持尾部以及是否可读取。
  • GetTrailer(string trailerName) - 从响应获取请求的尾随标头。

更改原因

在 gRPC 等方案中,尾部是关键功能。 将尾部合并到请求标头会使用户感到困惑。

HttpRequest 上使用尾部相关扩展方法访问尾部。

类别

ASP.NET Core

受影响的 API

HttpRequest.Headers


Kestrel:已删除并公开传输抽象

作为远离“pubternal”API 的一部分,Kestrel 传输层 API 被公开为 Microsoft.AspNetCore.Connections.Abstractions 库中的公共接口。

引入的版本

3.0

旧行为

  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions 库中提供传输相关的抽象。
  • ListenOptions.NoDelay 属性可用。

新行为

  • Microsoft.AspNetCore.Connections.Abstractions 库中引入 IConnectionListener 接口以公开 ...Transport.Abstractions 库最常用的功能。
  • 现在提供传输选项 NoDelayLibuvTransportOptionsSocketTransportOptions)。
  • SchedulingMode 不再可用。

更改原因

ASP.NET Core 3.0 已从“pubternal”API 移出。

类别

ASP.NET Core

受影响的 API


本地化:ResourceManagerWithCultureStringLocalizer 和 WithCulture 被标记为过时

ResourceManagerWithCultureStringLocalizer 类和 WithCulture 接口成员通常是造成本地化用户混淆的原因,尤其是在创建自己的 IStringLocalizer 实现时。 这些项给用户留下了 IStringLocalizer 实例“按语言、按资源”的印象。 实际上,实例应该仅“按资源”。 搜索的语言由 CultureInfo.CurrentUICulture 在执行时确定。 为了消除混淆来源,这些 API 在 ASP.NET Core 3.0 Preview 3 中被标记为过时。 将从未来版本中删除这些 API。

有关上下文,请参阅 dotnet/aspnetcore#3324。 有关讨论,请参阅 dotnet/aspnetcore#7756

引入的版本

3.0

旧行为

方法未标记为 Obsolete

新行为

方法被标记为 Obsolete

更改原因

API 表示一个不推荐使用的用例。 本地化设计存在混淆。

建议改用 ResourceManagerStringLocalizer。 允许 CurrentCulture 设置区域性。 如果没有这个选项,请创建并使用 ResourceManagerWithCultureStringLocalizer 的副本。

类别

ASP.NET Core

受影响的 API


日志记录:已将 DebugLogger 类设为内部类

在 ASP.NET Core 3.0 之前,DebugLogger 的访问修饰符为 public。 在 ASP.NET Core 3.0 中,访问修饰符更改为 internal

引入的版本

3.0

更改原因

正在进行更改以便:

  • 强制执行与其他记录器(如 ConsoleLogger)实现的一致性。
  • 减少 API 图面。

使用 AddDebugILoggingBuilder 扩展方法来启用调试日志记录。 如果需要手动注册服务,DebugLoggerProvider 也仍为 public

类别

ASP.NET Core

受影响的 API

Microsoft.Extensions.Logging.Debug.DebugLogger


MVC:从控制器操作名称中删除了异步后缀

作为寻址 dotnet/aspnetcore#4849 的一部分,ASP.NET Core MVC 默认从操作名称中剪裁后缀 Async。 从 ASP.NET Core 3.0 开始,这一更改会影响路由和链接生成。

引入的版本

3.0

旧行为

考虑以下 ASP.NET Core MVC 控制器:

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

此操作可通过 Product/ListAsync 进行路由。 链接生成需要指定 Async 后缀。 例如:

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

新行为

在 ASP.NET Core 3.0 中,操作可通过 Product/List 进行路由。 链接生成代码应省略 Async 后缀。 例如:

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

此更改不会影响使用 [ActionName] 属性指定的名称。 可以通过在 Startup.ConfigureServices 中将 MvcOptions.SuppressAsyncSuffixInActionNames 设置为 false 来禁用新行为:

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

更改原因

按照约定,异步 .NET 方法以 Async 为后缀。 但是,当方法定义 MVC 操作时,不需要使用 Async 后缀。

如果应用依赖于保留名称的 Async 后缀的 MVC 操作,请选择下列缓解措施之一:

  • 使用 [ActionName] 属性以保留原始名称。
  • 通过在 Startup.ConfigureServices 中将 MvcOptions.SuppressAsyncSuffixInActionNames 设置为 false 来完全禁用重命名:
services.AddMvc(options =>
{
   options.SuppressAsyncSuffixInActionNames = false;
});

类别

ASP.NET Core

受影响的 API


MVC:JsonResult 已移至 Microsoft.AspNetCore.Mvc.Core

JsonResult 已移至 Microsoft.AspNetCore.Mvc.Core 程序集。 此类型用于在 Microsoft.AspNetCore.Mvc.Formatters.Json 中进行定义。 已将程序集级别 [TypeForwardedTo] 属性添加到 Microsoft.AspNetCore.Mvc.Formatters.Json,以便为大多数用户解决此问题。 使用第三方库的应用可能会遇到问题。

引入的版本

3.0 预览版 6

旧行为

已成功生成使用基于 2.2 的库的应用。

新行为

使用基于 2.2 的库的应用无法进行编译。 提供了包含以下文本变体的错误:

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

有关此类问题的示例,请参阅 dotnet/aspnetcore#7220

更改原因

aspnet/Announcements#325 所述,对 ASP.NET Core 组成进行平台级别的更改。

根据 2.2 版本的 Microsoft.AspNetCore.Mvc.Formatters.Json 编译的库可能需要重新编译才能解决所有使用者的问题。 如果受到影响,请与库作者联系。 请求重新编译库以面向 ASP.NET Core 3.0。

类别

ASP.NET Core

受影响的 API

Microsoft.AspNetCore.Mvc.JsonResult


MVC:已弃用预编译工具

在 ASP.NET Core 1.1 中,引入了 Microsoft.AspNetCore.Mvc.Razor.ViewCompilation(MVC 预编译工具)包以添加对发布时进行 Razor 文件(.cshtml 文件)编译的支持。 在 ASP.NET Core 2.1 中,引入了 Razor SDK,以扩展预编译工具的功能。 Razor SDK 添加了对生成时和发布时进行 Razor 文件编译的支持。 SDK 在生成时验证 .cshtml 文件的正确性,同时缩短应用的启动时间。 默认情况下,Razor SDK 处于启用状态,并且不需要任何手势即可开始使用。

在 ASP.NET Core 3.0 中,已删除 ASP.NET Core 1.1 时代的 MVC 预编译工具。 早期的包版本将继续收到修补版本中的重要 Bug 和安全修补程序。

引入的版本

3.0

旧行为

Microsoft.AspNetCore.Mvc.Razor.ViewCompilation 包用于预编译 MVC Razor 视图。

新行为

Razor SDK 本机支持此功能。 Microsoft.AspNetCore.Mvc.Razor.ViewCompilation 包不再更新。

更改原因

Razor SDK 提供更多的功能并在生成时验证 .cshtml 文件的正确性。 SDK 还会缩短应用的启动时间。

对于 ASP.NET Core 2.1 或更高版本的用户,更新以在 Razor SDK 中使用本机支持进行预编译。 如果 Bug 或缺失的功能阻止迁移到 Razor SDK,请在 dotnet/aspnetcore 中提出问题。

类别

ASP.NET Core

受影响的 API


MVC:“Pubternal”类型已更改为内部类型

在 ASP.NET Core 3.0 中,MVC 中的所有“pubternal”类型都已更新为 public(在受支持的命名空间中)或 internal(根据需要)。

更改描述

在 ASP.NET Core 中,“pubternal”类型声明为 public,但驻留在后缀为 .Internal 的命名空间中。 尽管这些类型为 public,但它们没有支持策略,并且可能会发生中断性变更。 遗憾的是,经常会意外使用这些类型,导致对这些项目做出中断性变更,并使维护框架的能力受到限制。

引入的版本

3.0

旧行为

MVC 中的某些类型为 public,但在 .Internal 命名空间中。 这些类型没有支持策略,并且可能会发生中断性变更。

新行为

所有此类类型都将更新为 public(在受支持的命名空间中)或标记为 internal

更改原因

经常会意外使用“pubternal”类型,导致对这些项目做出中断性变更,并使维护框架的能力受到限制。

如果使用的类型已真正成为 public 且已移动到新的受支持的命名空间中,请更新引用以匹配新命名空间。

如果使用的类型已标记为 internal,则需要查找替代方法。 永远不支持将以前的“pubternal”类型用于公共用途。 如果这些命名空间中的特定类型对应用至关重要,请在 dotnet/aspnetcore 中提出问题。 可以考虑将请求的类型设为 public

类别

ASP.NET Core

受影响的 API

此更改包括以下命名空间中的类型:

  • 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 兼容性填充码

从 ASP.NET Core 3.0 开始,不再提供 Microsoft.AspNetCore.Mvc.WebApiCompatShim 包。

更改描述

Microsoft.AspNetCore.Mvc.WebApiCompatShim (WebApiCompatShim) 包在 ASP.NET Core 中提供了与 ASP.NET 4.x Web API 2 的部分兼容性,以简化将现有 Web API 实现迁移到 ASP.NET Core 的工作。 但是,使用 WebApiCompatShim 的应用不会从最近 ASP.NET Core 版本中提供的与 API 相关的功能中获益。 此类功能包括改进的开放 API 规范生成、标准化错误处理和客户端代码生成。 为了更好地专注于 3.0 中的 API 工作,已删除 WebApiCompatShim。 使用 WebApiCompatShim 的现有应用应迁移到较新的 [ApiController] 模型。

引入的版本

3.0

更改原因

Web API 兼容性填充码是一种迁移工具。 它限制用户对 ASP.NET Core 中添加的新功能的访问。

删除此填充码的使用,直接迁移到 ASP.NET Core 本身中的类似功能。

类别

ASP.NET Core

受影响的 API

Microsoft.AspNetCore.Mvc.WebApiCompatShim


Razor:已删除 RazorTemplateEngine API

已删除 RazorTemplateEngine API,该内容已替换为 Microsoft.AspNetCore.Razor.Language.RazorProjectEngine

有关讨论,请参阅 GitHub 问题 dotnet/aspnetcore#25215

引入的版本

3.0

旧行为

可创建模板引擎并将其用于分析和生成 Razor 文件的代码。

新行为

可创建 RazorProjectEngine,使其提供与 RazorTemplateEngine 相同类型的信息,以分析和生成 Razor 文件的代码。 RazorProjectEngine 也可提供额外的配置级别。

更改原因

RazorTemplateEngine 与现有实现过于紧密耦合。 在尝试正确配置 Razor 分析/生成管道时,这种紧密耦合会导致更多问题。

请使用 RazorProjectEngine,而不是 RazorTemplateEngine。 请考虑以下示例。

创建和配置 RazorProjectEngine
RazorProjectEngine projectEngine =
    RazorProjectEngine.Create(RazorConfiguration.Default,
        RazorProjectFileSystem.Create(@"C:\source\repos\ConsoleApp4\ConsoleApp4"),
        builder =>
        {
            builder.ConfigureClass((document, classNode) =>
            {
                classNode.ClassName = "MyClassName";

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

            // More configuration can go here
        });
生成 Razor 文件的代码
RazorProjectItem item = projectEngine.FileSystem.GetItem(
    @"C:\source\repos\ConsoleApp4\ConsoleApp4\Example.cshtml",
    FileKinds.Legacy);
RazorCodeDocument output = projectEngine.Process(item);

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

类别

ASP.NET Core

受影响的 API

  • RazorTemplateEngine
  • RazorTemplateEngineOptions

Razor:运行时编译已移到包

支持 Razor 视图的运行时编译,已将 Razor Pages 移动到单独的包中。

引入的版本

3.0

旧行为

无需额外的包,即可使用运行时编译。

新行为

此功能已移至 Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 包中。

以下 API 以前在 Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions 中提供,用于支持运行时编译。 现在可通过 Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.MvcRazorRuntimeCompilationOptions 获取 API。

  • RazorViewEngineOptions.FileProviders 现为 MvcRazorRuntimeCompilationOptions.FileProviders
  • RazorViewEngineOptions.AdditionalCompilationReferences 现为 MvcRazorRuntimeCompilationOptions.AdditionalReferencePaths

此外,已删除 Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions.AllowRecompilingViewsOnFileChange。 默认情况下,通过引用 Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 包来启用对文件更改的重新编译。

更改原因

此更改是删除 Roslyn 上的 ASP.NET Core 共享框架依赖项所必需的。

需要对 Razor 文件进行运行时编译或重新编译的应用应执行以下步骤:

  1. 添加对 Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 包的引用。

  2. 更新项目的 Startup.ConfigureServices 方法以包含对 AddRazorRuntimeCompilation 的调用。 例如:

    services.AddMvc()
        .AddRazorRuntimeCompilation();
    

类别

ASP.NET Core

受影响的 API

Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions


会话状态:已删除过时的 API

已删除用于配置会话 cookie 的过时 API。 有关详细信息,请参阅 aspnet/Announcements#257

引入的版本

3.0

更改原因

此更改强制实施跨 API 的一致性来配置使用 cookie 的功能。

将已删除的 API 的使用迁移到其更新的替换项。 请看下面 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;
    });
}

类别

ASP.NET Core

受影响的 API


共享框架:从 Microsoft.AspNetCore.App 中删除了程序集

从 ASP.NET Core 3.0 开始,ASP.NET Core 共享框架 (Microsoft.AspNetCore.App) 只包含 Microsoft 完全开发、支持和可服务的第一方程序集。

更改描述

将这一更改视为重新定义 ASP.NET Core“平台”的边界。任何人都可通过 GitHub 生成共享框架的源代码,共享框架将继续为应用提供 .NET Core 共享框架的现有优势。 一些优势包括部署大小更小、集中修补和启动时间更快。

作为此更改的一部分,Microsoft.AspNetCore.App 中引入了一些值得注意的重大更改。

引入的版本

3.0

旧行为

项目通过项目文件中的 <PackageReference> 元素引用了 Microsoft.AspNetCore.App

此外,Microsoft.AspNetCore.App 包含以下子组件:

  • Json.NET (Newtonsoft.Json)
  • Entity Framework Core(以 Microsoft.EntityFrameworkCore. 为前缀的程序集)
  • Roslyn (Microsoft.CodeAnalysis)

新行为

Microsoft.AspNetCore.App 的引用不再需要项目文件中的 <PackageReference> 元素。 .NET Core SDK 支持名为 <FrameworkReference> 的新元素,该元素将替代对 <PackageReference> 的使用。

有关详细信息,请参阅 dotnet/aspnetcore#3612

Entity Framework Core 作为 NuGet 包提供。 此更改将使随附模型与 .NET 上的所有其他数据访问库保持一致。 它在支持各种 .NET 平台的同时,为 Entity Framework Core 提供最简单的途径来继续创新。 将 Entity Framework Core 移出共享框架不会影响其作为 Microsoft 开发、支持和可服务的库的状态。 .NET Core 支持策略继续支持此功能。

Json.NET 和 Entity Framework Core 可继续使用 ASP.NET Core。 但是,它们不会包含在共享框架中。

有关详细信息,请参阅 .NET Core 3.0 中 JSON 的未来。 另请参阅从共享框架中删除的二进制文件的完整列表

更改原因

此更改简化了 Microsoft.AspNetCore.App 的使用,并减少了 NuGet 包与共享框架之间的重复。

有关此更改动机的详细信息,请参阅博客文章

从 ASP.NET Core 3.0 开始,项目不需要使用 Microsoft.AspNetCore.App 中的程序集作为 NuGet 包。 为了简化 ASP.NET Core 共享框架的定位和使用,已不再生成自 ASP.NET Core 1.0 以来提供的许多 NuGet 包。 通过将 <FrameworkReference> 用于 Microsoft.AspNetCore.App,应用仍可使用这些包提供的 API。 常见的 API 示例包括 Kestrel、MVC 和 Razor。

此更改不适用于通过 ASP.NET Core 2.x 中的 Microsoft.AspNetCore.App 引用的所有二进制文件。 值得注意的例外包括:

  • 继续以 .NET Standard 为目标的 Microsoft.Extensions 库将以 NuGet 包的形式提供(请参阅 https://github.com/dotnet/extensions)。
  • 不属于 Microsoft.AspNetCore.App 的 ASP.NET Core 团队生成的 API。 例如,以下组件以 NuGet 包的形式提供:
  • 用于保留对 Json.NET 的支持的 MVC 扩展。 API 作为 NuGet 包提供,以支持使用 Json.NET 和 MVC。 有关更多详细信息,请参阅 ASP.NET Core 迁移指南
  • SignalR .NET 客户端继续支持 .NET Standard 并作为 NuGet 包提供。 它可用于许多 .NET 运行时,例如 Xamarin 和 UWP。

有关详细信息,请参阅停止为 3.0 中的共享框架程序集生成包。 有关讨论,请参阅 dotnet/aspnetcore#3757

类别

ASP.NET Core

受影响的 API


共享框架:已删除 Microsoft.AspNetCore.All

从 ASP.NET Core 3.0 开始,不再生成 Microsoft.AspNetCore.All 元包和匹配的 Microsoft.AspNetCore.All 共享框架。 此包在 ASP.NET Core 2.2 中提供,并将继续接收 ASP.NET Core 2.1 中的服务更新。

引入的版本

3.0

旧行为

应用可以使用 Microsoft.AspNetCore.All 元包来针对 .NET Core 上的 Microsoft.AspNetCore.All 共享框架。

新行为

.NET Core 3.0 不包含 Microsoft.AspNetCore.All 共享框架。

更改原因

Microsoft.AspNetCore.All 元包包含了大量外部依赖项。

迁移项目以使用 Microsoft.AspNetCore.App 框架。 以前在 Microsoft.AspNetCore.All 中可用的组件在 NuGet 上仍然可用。 这些组件现可与应用一起部署,而不是包含在共享框架中。

类别

ASP.NET Core

受影响的 API


SignalR:已替换 HandshakeProtocol.SuccessHandshakeData

已删除 HandshakeProtocol.SuccessHandshakeData 字段,并将其替换为一个 Helper 方法,该方法根据特定 IHubProtocol 生成成功的握手响应。

引入的版本

3.0

旧行为

HandshakeProtocol.SuccessHandshakeDatapublic static ReadOnlyMemory<byte> 字段。

新行为

HandshakeProtocol.SuccessHandshakeData 已被 staticGetSuccessfulHandshake(IHubProtocol protocol) 方法替换,该方法根据指定的协议返回 ReadOnlyMemory<byte>

更改原因

握手响应中添加了其他字段,这些字段是非常量,并会根据所选协议的不同而变化。

无。 此类型不适用于从用户代码使用。 它是 public 类型,因此可以在 SignalR 服务器和客户端之间共享。 它还可以由以 .NET 编写的客户 SignalR 客户端使用。 SignalR 用户不应受此更改的影响

类别

ASP.NET Core

受影响的 API

HandshakeProtocol.SuccessHandshakeData


SignalR:已删除 HubConnection ResetSendPing 和 ResetTimeout 方法

已从 SignalR HubConnection API 中删除了 ResetSendPingResetTimeout 方法。 这些方法最初仅供内部使用,但已在 ASP.NET Core 2.2 中公开。 从 ASP.NET Core 3.0 预览版 4 开始,这些方法将不可用。 有关讨论,请参阅 dotnet/aspnetcore#8543

引入的版本

3.0

旧行为

API 可用。

新行为

API 已删除。

更改原因

这些方法最初仅供内部使用,但已在 ASP.NET Core 2.2 中公开。

不要使用这些方法。

类别

ASP.NET Core

受影响的 API


SignalR:已更改 HubConnectionContext 构造函数

SignalR 的 HubConnectionContext 构造函数已更改为接受选项类型(而不是多个参数),以接受经得起未来考验的添加选项。 此更改使用单个接受选项类型的构造函数替换两个构造函数。

引入的版本

3.0

旧行为

HubConnectionContext 有两个构造函数:

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

新行为

这两个构造函数已被删除并已替换为一个构造函数:

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

更改原因

新的构造函数使用新的选项对象。 因此,可以在以后展开 HubConnectionContext 的功能,而无需执行更多的构造函数和中断性变更。

而不是使用以下构造函数:

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

使用以下构造函数:

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

类别

ASP.NET Core

受影响的 API


SignalR:已更改 JavaScript 客户端包名称

在 ASP.NET Core 3.0 预览版 7 中,SignalR JavaScript 客户端包名称从 @aspnet/signalr 更改为 @microsoft/signalr。 由于 Azure SignalR 服务,名称更改反映了 SignalR 不只是在 ASP.NET Core 应用中有用这一事实。

若要对此更改做出反应,请更改 package.jsonrequire 文件、 语句和 ECMAScript import 语句中的引用。 在此重命名过程中,不会更改 API。

有关讨论,请参阅 dotnet/aspnetcore#11637

引入的版本

3.0

旧行为

客户端包以前命名为 @aspnet/signalr

新行为

客户端包现在命名为 @microsoft/signalr

更改原因

由于 Azure SignalR 服务,名称更改阐明了 SignalR 在 ASP.NET Core 应用之外也很有用。

切换到新包 @microsoft/signalr

类别

ASP.NET Core

受影响的 API


SignalR:UseSignalR 和 UseConnections 方法已标记为过时

在 ASP.NET Core 3.0 中,方法 UseConnectionsUseSignalR 以及类 ConnectionsRouteBuilderHubRouteBuilder 被标记为过时。

引入的版本

3.0

旧行为

SignalR 中心路由是使用 UseSignalRUseConnections 配置的。

新行为

配置路由的旧方法已弃用,并已替换为终结点路由。

更改原因

正在将中间件移动到新的终结点路由系统。 添加中间件的旧方法即将过时。

UseSignalR 替换为 UseEndpoints

旧代码:

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

新代码:

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

类别

ASP.NET Core

受影响的 API


SPA:SpaServices 和 NodeServices 已标记为过时

自 ASP.NET Core 2.1 起,以下 NuGet 包的内容都是不必要的。 因此,下列包将被标记为过时:

出于相同的原因,以下 npm 模块将被标记为已弃用:

上述包和 npm 模块稍后将从 .NET 5 中删除。

引入的版本

3.0

旧行为

已弃用的包和 npm 模块旨在将 ASP.NET Core 与各种单页应用 (SPA) 框架集成。 此类框架包括 Angular、React 和 React Redux。

新行为

Microsoft.AspNetCore.SpaServices.Extensions NuGet 包中存在新的集成机制。 自 ASP.NET Core 2.1 起,包仍然是 Angular 和 React 项目模板的基础。

更改原因

ASP.NET Core 支持与各种单页应用 (SPA) 框架(包括 Angular、React 和 React Redux)集成。 最初,与这些框架的集成是通过 ASP.NET Core 特定组件实现的,这些组件用于处理服务器端预呈现和与 Webpack 集成等情况。 随着时间的推移,行业标准也发生了变化。 每个 SPA 框架都发布了其自己的标准命令行接口。 例如,Angular CLI 和 create-react-app。

当 ASP.NET Core 2.1 于 2018 年 5 月发布时,团队对标准的变化做出了响应。 提供了一种更新且更简单的方法来与 SPA 框架自身的工具链集成。 自 ASP.NET Core 2.1 起,包 Microsoft.AspNetCore.SpaServices.Extensions 中存在新的集成机制,且仍是 Angular 和 React 项目模板的基础。

为了阐明较低版本的 ASP.NET Core 特定组件不相关且不建议使用,请执行以下操作:

  • 2.1 之前的集成机制被标记为已过时。
  • 支持 npm 包被标记为已弃用。

如果正在使用这些包,请更新应用以使用以下功能:

  • Microsoft.AspNetCore.SpaServices.Extensions 包中。
  • 由使用的 SPA 框架提供

若要启用服务器端预呈现和热模块重载等功能,请参阅相应的 SPA 框架的文档。 Microsoft.AspNetCore.SpaServices.Extensions 中的功能未过时,将继续受到支持。

类别

ASP.NET Core

受影响的 API


SPA:SpaServices 和 NodeServices 不再回退到控制台记录器

除非配置了日志记录,否则 Microsoft.AspNetCore.SpaServicesMicrosoft.AspNetCore.NodeServices 不会显示控制台日志。

引入的版本

3.0

旧行为

Microsoft.AspNetCore.SpaServicesMicrosoft.AspNetCore.NodeServices 用于在未配置日志记录时自动创建控制台记录器。

新行为

除非配置了日志记录,否则 Microsoft.AspNetCore.SpaServicesMicrosoft.AspNetCore.NodeServices 不会显示控制台日志。

更改原因

需要与其他 ASP.NET Core 包实现日志记录的方式保持一致。

如果需要旧行为,若要配置控制台日志记录,请将 services.AddLogging(builder => builder.AddConsole()) 添加到 Setup.ConfigureServices 方法。

类别

ASP.NET Core

受影响的 API


目标框架:删除了 .NET Framework 支持

从 ASP.NET Core 3.0 开始,.NET Framework 不再是受支持的目标框架。

更改描述

.NET Framework 4.8 是 .NET Framework 的上一个主要版本。 新的 ASP.NET Core 应用应基于 .NET Core 构建。 从 .NET Core 3.0 版开始,可将 ASP.NET Core 3.0 视为 .NET Core 的一部分。

将 .NET Framework 和 ASP.NET Core 结合使用的客户可以使用 2.1 LTS 版本以完全受支持的方式继续。 至少在 2021 年 8 月 21 日之前,将继续提供对 2.1 的支持和服务。 根据 .NET 支持策略,此日期为声明 LTS 版本后三年。 .NET Framework 对 ASP.NET Core 2.1 包的支持将无限延期,类似于其他基于包的 ASP.NET 框架的服务策略

有关从 .NET Framework 移植到 .NET Core 的详细信息,请参阅移植到 .NET Core

Microsoft.Extensions 包(如日志记录、依赖项注入和配置)和 Entity Framework Core 不受影响。 它们将继续支持 .NET Standard。

有关此更改动机的详细信息,请参阅原始博客文章

引入的版本

3.0

旧行为

ASP.NET Core 应用可在 .NET Core 或 .NET Framework 上运行。

新行为

ASP.NET Core 应用只能在 .NET Core 上运行。

请执行以下一项操作:

  • 将应用保留在 ASP.NET Core 2.1 上。
  • 将应用和依赖项迁移到 .NET Core。

类别

ASP.NET Core

受影响的 API


Core .NET 库

报告版本的 API 现报告的是产品版本而不是文件版本

返回 .NET Core 中的版本的很多 API 现在返回的是产品版本,而不是文件版本。

更改描述

在 .NET Core 2.2 及更低版本中,Environment.VersionRuntimeInformation.FrameworkDescription 等方法以及 .NET Core 程序集的“文件属性”对话框反映的都是文件版本。 自 .NET Core 3.0 起,它们反映的是产品版本。

下图展示了由“Windows 资源管理器”文件属性对话框显示的 .NET Core 2.2(左侧)与 .NET Core 3.0(右侧)的 System.Runtime.dll 程序集版本信息区别 。

Difference in product version information

引入的版本

3.0

无。 此更改会使版本检测变得直观而非退化。

类别

Core .NET 库

受影响的 API


自定义 EncoderFallbackBuffer 实例无法递归回退

自定义 EncoderFallbackBuffer 实例无法以递归方式回退。 EncoderFallbackBuffer.GetNextChar() 的实现必须生成一个可转换为目标编码的字符序列。 否则会发生异常。

更改描述

在字符到字节的转码操作期间,运行时将检测格式不正确或不可转换的 UTF-16 序列,并将这些字符提供给 EncoderFallbackBuffer.Fallback 方法。 Fallback 方法确定应将哪些字符替换为原始不可转换数据,并通过在循环中调用 EncoderFallbackBuffer.GetNextChar 来释放这些字符。

然后,运行时尝试将这些替换字符转码为目标编码。 如果此操作成功,则运行时继续从原始输入字符串中的中断位置进行转码。

之前,EncoderFallbackBuffer.GetNextChar() 的自定义实现可以返回无法转换为目标编码的字符序列。 如果替换字符无法转码为目标编码,则运行时将使用替换字符再调用一次 EncoderFallbackBuffer.Fallback 方法,并要求 EncoderFallbackBuffer.GetNextChar() 方法返回新的替换序列。 此过程将一直继续,直到运行时最终看到格式正确的、可转换的替换,或直到达到最大递归计数。

从 .NET Core 3.0 开始,EncoderFallbackBuffer.GetNextChar() 的自定义实现必须返回可转换为目标编码的字符序列。 如果替换字符无法转码为目标编码,则引发 ArgumentException。 运行时将不再对 EncoderFallbackBuffer 实例进行递归调用。

仅当满足以下所有三个条件时,此行为才适用:

  • 运行时检测格式不正确的 UTF-16 序列或无法转换为目标编码的 UTF-16 序列。
  • 已指定自定义 EncoderFallback
  • 自定义 EncoderFallback 尝试替换新的格式不正确的或无法转换的 UTF-16 序列。

引入的版本

3.0

大多数开发人员都不需要执行任何操作。

如果应用程序使用自定义 EncoderFallbackEncoderFallbackBuffer 类,请确保 EncoderFallbackBuffer.Fallback 的实现使用格式正确的 UTF-16 数据(该数据在运行时第一次调用 Fallback 方法时可直接转换为目标编码)填充回退缓冲区。

类别

Core .NET 库

受影响的 API


浮点格式设置和分析行为已更改

浮点分析和格式设置行为(由 DoubleSingle 类型实现)现符合 IEEE 标准。 这可确保 .NET 中浮点类型的行为与符合 IEEE 标准的语言的行为一致。 例如,double.Parse("SomeLiteral") 应始终与 C# 为 double x = SomeLiteral 生成的结果匹配。

更改描述

在 .NET Core 2.2 及更低版本中,通过 Double.ToStringSingle.ToString 进行格式设置的行为,以及使用 Double.ParseDouble.TryParseSingle.ParseSingle.TryParse 进行分析的行为不符合 IEEE 标准。 因此,没法保证值在没有任何受支持的标准或自定义格式字符串的情况下双向传输。 对于某些输入,尝试分析已设置格式的值可能会失败;而对于其他输入,分析后的值与原始值不相等。

自 .NET Core 3.0 起,浮点分析和格式设置操作均符合 IEEE 754 标准。

下表显示了两个代码片段,以及 .NET Core 2.2 和 .NET Core 3.1 之间的输出更改情况。

代码片段 .NET Core 2.2 上的输出 .NET Core 3.1 上的输出
Console.WriteLine((-0.0).ToString()); 0 -0
var value = -3.123456789123456789;
Console.WriteLine(value == double.Parse(value.ToString()));
False True

有关浮点改进的详细信息,请参阅 Floating-point parsing and formatting improvements in .NET Core 3.0(.NET Core 3.0 中浮点分析和格式设置改进)博客文章。

引入的版本

3.0

.NET Core 3.0 中浮点分析和格式设置改进博客文章的“对现有代码的潜在影响”部分建议,如果要维护以前的行为,可以对代码进行一些更改。

  • 对于格式设置中的一些差异,可以通过指定不同的格式字符串获得与以前行为等效的行为。
  • 对于分析方面的差异,没有回退到以前行为的机制。

类别

Core .NET 库

受影响的 API


浮点分析操作不再失败或引发 OverflowException

浮点分析方法在分析数值超出 SingleDouble 浮点类型范围的字符串时,不再引发 OverflowException 或返回 false

更改描述

在 .NET Core2.2 和早期版本中,Double.ParseSingle.Parse 方法对超出其各自类型范围的值会引发 OverflowException。 对于超出范围的数值的字符串表示形式,Double.TryParseSingle.TryParse 方法返回 false

从 .NET Core 3.0 开始,分析超出范围的数值字符串时,Double.ParseDouble.TryParseSingle.ParseSingle.TryParse 方法不再失败。 相反,Double 分析方法对于超过 Double.MaxValue 的值返回 Double.PositiveInfinity,对于小于 Double.MinValue 的值返回 Double.NegativeInfinity。 同样,Single 分析方法对于超过 Single.MaxValue 的值返回 Single.PositiveInfinity,对于小于 Single.MinValue 的值返回 Single.NegativeInfinity

此更改是为了改进 IEEE 754:2008 的符合性。

引入的版本

3.0

此更改会以两种方式之一影响你的代码:

  • 你的代码依赖于 OverflowException 在发生溢出时执行的处理程序。 在这种情况下,应删除 catch 语句,并在 If 语句中放置必要的代码,以测试 Double.IsInfinitySingle.IsInfinity 是否为 true

  • 代码假设浮点值不是 Infinity。 在这种情况下,应添加必要的代码来检查 PositiveInfinityNegativeInfinity 的浮点值。

类别

Core .NET 库

受影响的 API


InvalidAsynchronousStateException 已移到另一程序集

InvalidAsynchronousStateException 类已移动。

更改描述

在 .NET Core 2.2 及更低版本中,InvalidAsynchronousStateException 位于 System.ComponentModel.TypeConverter 程序集中 。

而自 .NET Core 3.0 起,它位于 System.ComponentModel.Primitives 程序集中 。

引入的版本

3.0

此更改仅影响这样的应用程序,它们通过调用 Assembly.GetType 等方法或调用假设类型位于特定程序集中的 Activator.CreateInstance 的重载,使用反射过程来加载 InvalidAsynchronousStateException。 如果是这种情况,可以更新在方法调用中引用的程序集,以反映出类型的新程序集位置。

类别

Core .NET 库

受影响的 API

无。


替换格式错误的 UTF-8 字节序列将遵循 Unicode 准则

UTF8Encoding 类在字节到字符转码操作期间遇到格式错误的 UTF-8 字节序列时,它将在输出字符串中用“�”(U+FFFD 替换字符)替换该序列。 .NET Core 3.0 与以前版本的 .NET Core 和 .NET Framework 的不同之处在于,在转码操作期间按照 Unicode 最佳做法执行此替换。

这是在整个 .NET 中改进 UTF-8 处理的较大工作量(包括通过新的 System.Text.Unicode.Utf8System.Text.Rune 类型)的一部分。 为 UTF8Encoding 类型提供了改进的错误处理机制,以便生成与新引入的类型一致的输出。

更改描述

从 .NET Core 3.0 开始,当将字节转码为字符时,UTF8Encoding 类会根据 Unicode 最佳做法执行字符替换。 Unicode 标准 12.0 版第 3.9 节 (PDF) 的 “U+FFFD 替换最大子部分”标题中描述了使用的替换机制。

仅当 输入字节序列包含格式错误的 UTF-8 数据时,此行为才适用。 此外,如果已通过 throwOnInvalidBytes: true 构造了 UTF8Encoding 实例,则 UTF8Encoding 实例将继续对无效输入引发,而不是执行 U+FFFD 替换。 有关 UTF8Encoding 构造函数的详细信息,请参阅 UTF8Encoding(Boolean, Boolean)

下表通过无效的 3 字节输入说明了此更改的影响:

格式无效的 3 字节输入 .NET Core 3.0 之前的输出 从 .NET Core 3.0 开始的输出
[ ED A0 90 ] [ FFFD FFFD ](2 字符输出) [ FFFD FFFD FFFD ](3 字符输出)

根据以前链接的 Unicode 标准 PDF 的表 3-9 ,此 3 字符输出为首选输出。

引入的版本

3.0

开发人员一方不需要执行任何操作。

类别

Core .NET 库

受影响的 API


TypeDescriptionProviderAttribute 已移到另一程序集

TypeDescriptionProviderAttribute 类已移动。

更改描述

在 .NET Core 2.2 及更低版本中,TypeDescriptionProviderAttribute 位于 System.ComponentModel.TypeConverter 程序集中。

而自 .NET Core 3.0 起,它位于 System.ObjectModel 程序集中

引入的版本

3.0

此更改仅影响这样的应用程序,它们通过调用 Assembly.GetType 等方法或调用假设类型位于特定程序集中的 Activator.CreateInstance 的重载,使用反射过程来加载 TypeDescriptionProviderAttribute 类型。 若是如此,应更新在方法调用反射的程序集,以反射出类型的新程序集位置。

类别

Windows 窗体

受影响的 API

无。


ZipArchiveEntry 不再处理具有不一致条目大小的存档

Zip 存档在中央目录和本地标头中列出压缩的大小和未压缩的大小。 条目数据本身还指示其大小。 在 .NET Core 2.2 及更早版本中,永远不会对这些值进行一致性检查。 从 .NET Core 3.0 开始,对它们进行一致性检查。

更改描述

在 .NET Core 2.2 及更早版本中,即使本地标头与 zip 文件的中央标头不一致,ZipArchiveEntry.Open() 也会成功。 即使数据长度超出了中央目录/本地标头中列出的未压缩文件大小,数据也会一直进行解压缩,直到达到压缩流的末尾。

从 .NET Core 3.0 开始,ZipArchiveEntry.Open() 方法会检查本地标头和中央标头是否在条目的压缩大小和未压缩大小方面保持一致。 如果不是这样,则该方法在存档的本地标头和/或数据描述符列表大小与 zip 文件的中央目录不一致时会引发 InvalidDataException。 当读取条目时,解压缩的数据将被截断为标头中列出的未压缩文件大小。

进行此更改是为了确保 ZipArchiveEntry 正确表示其数据的大小并且只读取该数据量。

引入的版本

3.0

对出现这些问题的所有 zip 存档重新打包。

类别

Core .NET 库

受影响的 API


FieldInfo.SetValue 将对静态、仅初始化字段引发异常

从 .NET Core 3.0 开始,当你尝试通过调用 System.Reflection.FieldInfo.SetValue 在静态 InitOnly 字段上设置值时,将引发异常。

更改描述

在 .NET Framework 和 3.0 之前的 .NET Core 版本中,你可以通过调用 System.Reflection.FieldInfo.SetValue 来设置初始化后为常量的静态字段的值(C# 中的 readonly)。 但是,以这种方式设置此类字段导致了不可预测的行为,具体取决于目标框架和优化设置。

在 .NET Core 3.0 及更高版本中,当对静态 InitOnly 字段调用 SetValue 时,将引发 System.FieldAccessException 异常。

提示

InitOnly 字段是只能在声明它时或位于包含类的构造函数中时设置的字段。 换句话说,它在初始化后为常量。

引入的版本

3.0

初始化静态构造函数中的静态 InitOnly 字段。 这同时适用于动态和非动态类型。

或者,可以从字段中删除 FieldAttributes.InitOnly 属性,然后调用 FieldInfo.SetValue

类别

Core .NET 库

受影响的 API


将 GroupCollection 传递到采用 IEnumerable<T> 的扩展方法需要消除歧义

调用在 GroupCollection 上采用 IEnumerable<T> 的扩展方法时,必须使用强制转换来消除该类型的歧义。

更改说明

从 .NET Core 3.0 开始,System.Text.RegularExpressions.GroupCollection 除了实现 IEnumerable<Group> 等类型之外,还会实现 IEnumerable<KeyValuePair<String,Group>>。 调用采用 IEnumerable<T> 的扩展方法时,这会导致歧义。 如果在 GroupCollection 实例上调用此类扩展方法,例如 Enumerable.Count,你将看到以下编译器错误:

CS1061:“GroupCollection”未包含“Count”的定义,并且找不到可接受第一个“GroupCollection”类型参数的可访问扩展方法“Count”(是否缺少 using 指令或程序集引用?)

在早期版本的 .NET 中,没有歧义,也没有编译器错误。

引入的版本

3.0

更改原因

这是意外的中断性变更。 由于此更改已经有一段时间了,所以我们不打算将其还原。 此外,此类更改本身就会造成中断。

对于 GroupCollection 实例,使用强制转换对接受 IEnumerable<T> 的扩展方法的调用消除歧义。

// Without a cast - causes CS1061.
match.Groups.Count(_ => true)

// With a disambiguating cast.
((IEnumerable<Group>)m.Groups).Count(_ => true);

类别

Core .NET 库

受影响的 API

任何接受 IEnumerable<T> 的扩展方法都会受到影响。 例如:


密码

Linux 上的根证书不再支持“BEGIN TRUSTED CERTIFICATE”语法

Linux 和其他类似 Unix 的系统(但不是 macOS)上的根证书可以采用两种形式显示:标准 BEGIN CERTIFICATE PEM 标头和特定于 OpenSSL 的 BEGIN TRUSTED CERTIFICATE PEM 标头。 后一种语法允许进行其他配置,这些配置已导致与 .NET Core 的 System.Security.Cryptography.X509Certificates.X509Chain 类之间的兼容性问题。 从 .NET Core 3.0 开始,链引擎不再加载 BEGIN TRUSTED CERTIFICATE 根证书内容。

更改描述

以前,BEGIN CERTIFICATEBEGIN TRUSTED CERTIFICATE 语法均用于填充根信任列表。 如果使用了 BEGIN TRUSTED CERTIFICATE 语法,并且在文件中指定了其他选项,则 X509Chain 可能报告已明确禁止链信任 (X509ChainStatusFlags.ExplicitDistrust)。 但是,如果在以前加载的文件中同时使用 BEGIN CERTIFICATE 语法指定了证书,则允许链信任。

从 .NET Core 3.0 开始,不再读取 BEGIN TRUSTED CERTIFICATE 内容。 如果还没有通过标准 BEGIN CERTIFICATE 语法指定证书,则 X509Chain 会报告根不受信任 (X509ChainStatusFlags.UntrustedRoot)。

引入的版本

3.0

大多数应用程序不受此更改的影响,但是由于权限问题而无法同时看到两个根证书源的应用程序可能会在升级后遇到意外的 UntrustedRoot 错误。

许多 Linux 分发版(或发行版)将根证书写入两个位置:每个文件一个证书目录和一个文件串联。 在某些发行版上,每个文件一个证书目录使用 BEGIN TRUSTED CERTIFICATE 语法,而一个文件串联则使用标准 BEGIN CERTIFICATE 语法。 请确保将任何自定义根证书作为 BEGIN CERTIFICATE 添加到这些位置中的至少一个位置,并且你的应用程序可以读取这两个位置。

典型的目录是 /etc/ssl/certs/ / ,典型的串联文件是 /etc/ssl/cert.pem。 使用命令 openssl version -d 来确定特定于平台的根目录,这可能不同于 /etc/ssl/。 例如,在 Ubuntu 18.04 上,目录是 /usr/lib/ssl/certs/,文件是 /usr/lib/ssl/cert.pem。 不过,/usr/lib/ssl/certs/ 是 /etc/ssl/certs/ 的符号链接,并且 /usr/lib/ssl/cert.pem 不存在。

$ openssl version -d
OPENSSLDIR: "/usr/lib/ssl"
$ ls -al /usr/lib/ssl
total 12
drwxr-xr-x  3 root root 4096 Dec 12 17:10 .
drwxr-xr-x 73 root root 4096 Feb 20 15:18 ..
lrwxrwxrwx  1 root root   14 Mar 27  2018 certs -> /etc/ssl/certs
drwxr-xr-x  2 root root 4096 Dec 12 17:10 misc
lrwxrwxrwx  1 root root   20 Nov 12 16:58 openssl.cnf -> /etc/ssl/openssl.cnf
lrwxrwxrwx  1 root root   16 Mar 27  2018 private -> /etc/ssl/private

类别

密码

受影响的 API


EnvelopedCms 默认为 AES-256 加密

EnvelopedCms 使用的默认对称加密算法已由 TripleDES 改为 AES-256。

更改描述

在以前的版本中,如果 EnvelopedCms 用于对数据加密但未通过构造函数重载指定对称加密算法,则使用 TripleDES/3DES/3DEA/DES3-EDE 算法对数据加密。

从 .NET Core 3.0 开始(通过 System.Security.Cryptography.Pkcs NuGet 包的 4.6.0 版本),默认算法已改为 AES-256 以实现算法现代化并提高默认选项的安全性。 如果消息收件人证书具有(非 EC)Diffie-Hellman 公钥,则由于底层平台的限制,加密操作可能会失败并显示 CryptographicException

在下面的示例代码中,如果在 .NET Core 2.2 或更早版本上运行,则使用 TripleDES 对数据加密。 如果在.NET Core 3.0 或更高版本上运行,则使用 AES-256 对数据加密。

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

引入的版本

3.0

如果该更改有负面影响,则可以通过在包含 AlgorithmIdentifier 类型参数的 EnvelopedCms 构造函数中显式指定加密算法标识符来还原 TripleDES 加密,例如:

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();

类别

密码

受影响的 API


RSAOpenSsl 密钥生成的最小大小已增加

在 Linux 上生成新 RSA 密钥的最小大小已从 384 位提高到 512 位。

更改描述

自 .NET Core 3.0 起,Linux 上 RSA.CreateRSAOpenSslRSACryptoServiceProvider 中 RSA 实例上的 LegalKeySizes 属性报告的最低合法密钥大小已从 384 增加到 512。

因此,在 .NET Core 2.2 及更早版本中,方法调用(如 RSA.Create(384))会成功。 在 .NET Core 3.0 及更高版本中,方法调用 RSA.Create(384) 会引发异常,指示大小太小。

此更改是因为在 Linux 上执行加密操作的 OpenSSL 在版本 1.0.2 与 1.1.0 之间提高了其最小值。 .NET Core 3.0 倾向于使用 OpenSSL 1.1.x 而不是 1.0.x,并提高了最小报告版本来反映这一新的更高的依赖项限制。

引入的版本

3.0

如果调用任何受影响的 API,请确保所有生成的密钥的大小不小于提供程序的最小值。

注意

384 位 RSA 已被视为不安全(512 位 RSA 也是如此)。 新式建议(例如 NIST 特别出版物 800-57 第 1 部分修订版 4)建议将 2048 位作为新生成的密钥的最小大小。

类别

密码

受影响的 API


.NET Core 3.0 倾向于使用 OpenSSL 1.1.x 而不是 OpenSSL 1.0.x

跨多个 Linux 分发工作的适用于 Linux 的 .NET Core 可同时支持 OpenSSL 1.0.x 和 OpenSSL 1.1.x。 .NET Core 2.1 和 .NET Core 2.2 首先查找 1.0.x,然后回退到 1.1.x;.NET Core 3.0 首先查找 1.1.x。 进行此更改是为了增加对新加密标准的支持。

此更改可能会影响库或应用程序,这些库或应用程序与 .NET Core 中的 OpenSSL 特定互操作类型进行平台互操作。

更改描述

在 .NET Core 2.2 及更早版本中,运行时倾向于加载 OpenSSL 1.0.x 而不是加载 1.1.x。 这意味着,与 OpenSSL 互操作的 IntPtrSafeHandle 类型倾向于与 libcrypto.so.1.0.0 / libcrypto.so.1.0 / libcrypto.so.10 一起使用。

从 .NET Core 3.0 开始,运行时倾向于加载 OpenSSL 1.1.x 而不是 OpenSSL 1.0.x,因此与 OpenSSL 互操作的 IntPtrSafeHandle 类型倾向于与 libcrypto.so.1.1 / libcrypto.so.11 / libcrypto.so.1.1.0 / libcrypto.so.1.1.1 一起使用。 因此,从 .NET Core 2.1 或 .NET Core 2.2 升级时,与 OpenSSL 直接互操作的库和应用程序的指针可能与 .NET Core 公开的值不兼容。

引入的版本

3.0

需要小心使用直接与 OpenSSL 操作的库和应用程序,确保它们使用的 OpenSSL 版本与 .NET Core 运行时相同。

所有将 .NET Core 加密类型中的 IntPtrSafeHandle 值直接用于 OpenSSL 的库或应用程序都应当将其使用的库的版本与新的 SafeEvpPKeyHandle.OpenSslVersion 属性进行比较,以确保指针兼容。

类别

密码

受影响的 API


CryptoStream.Dispose 仅在写入时转换最终块

用于完成 CryptoStream 操作的 CryptoStream.Dispose 方法不再尝试在读取时转换最终块。

更改说明

在以前的 .NET 版本中,如果用户在 Read 模式下使用 CryptoStream 时执行了不完整的读取操作,Dispose 方法可能会引发异常(例如,使用带有填充的 AES 时)。 引发异常是因为尝试转换最终块,但数据不完整。

在 .NET Core 3.0 及更高版本中,Dispose 不再尝试在读取时转换最终块,这会允许执行不完整的读取操作。

更改原因

由于此更改,当取消网络操作后,将允许从加密流中进行不完整的读取操作,而无需捕获异常。

引入的版本

3.0

大多数应用都不会受到此更改的影响。

如果应用程序先前在读取不完整的情况下捕获到异常,你可以删除相应 catch 块。 如果应用在哈希方案中使用了最终块的转换,则可能需要确保在释放所有流之前先对其进行读取。

类别

密码

受影响的 API


Entity Framework Core

Entity Framework Core 重大变更

全球化

“C”区域设置映射到固定区域设置

.NET Core 2.2 及更早版本依赖于默认 ICU 行为,该行为将“C”区域设置映射到 en_US_POSIX 区域设置。 En_US_POSIX 区域设置的排序行为并不可取,因为它不支持不区分大小写的字符串比较。 用户会遇到意外行为是因为部分 Linux 分发版将“C”区域设置设置为了默认区域设置。

更改说明

从 .NET Core 3.0 开始,“C”区域设置映射已更改为使用固定区域设置,而不是 en_US_POSIX。 “C”区域设置到固定的映射还应用于 Windows,以实现一致性。

将“C”映射到 en_US_POSIX 区域性会导致客户混乱,因为 en_US_POSIX 不支持不区分大小写的字符串排序/搜索操作。 由于“C”区域设置用作部分 Linux 分发版中的默认区域设置,因此客户在这些操作系统上会遭遇此类不良行为。

引入的版本

3.0

除了解此变更外,没有什么特别之处需要注意。 此变更仅影响使用“C”本地映射的应用程序。

类别

全球化

受影响的 API

所有排序规则和区域性 API 都会受到此变更的影响。


MSBuild

资源清单文件名更改

从 .NET Core 3.0 开始,默认情况下,MSBuild 会为资源文件生成不同的清单文件名。

引入的版本

3.0

更改描述

在 .NET Core 3.0 之前,如果没有为项目文件中的 EmbeddedResource 项指定 LogicalNameManifestResourceNameDependentUpon 元数据,则 MSBuild 会在 <RootNamespace>.<ResourceFilePathFromProjectRoot>.resources 模式中生成清单文件名。 如果未在项目文件中定义 RootNamespace,则其默认为项目名称。 例如,根项目目录中名为“Form1.resx”的资源文件的生成清单名称是“MyProject.Form1.resources”。

从 .NET Core 3.0 开始,如果资源文件与同名的源文件(例如 Form1.resx 和 Form1.cs)并置,则 MSBuild 将使用源文件中的类型信息在 <Namespace>.<ClassName>.resources 模式中生成清单文件名。 命名空间和类名称是从并置源文件的第一个类型中提取的。 例如,与名为“Form1.cs”的源文件并置的、名为“Form1.resx”的资源文件的生成清单名称是“MyNamespace.Form1.resources”。 需要注意的一点是,文件名的第一部分不同于早期版本的 .NET Core(是 MyNamespace,而不是 MyProject)。

注意

如果已在项目文件中的 EmbeddedResource 项上指定 LogicalNameManifestResourceNameDependentUpon 元数据,则此更改不会影响该资源文件。

此重大更改是在 .NET Core 项目中添加 EmbeddedResourceUseDependentUponConvention 属性时引入的。 默认情况下,不会在 .NET Core 项目文件中显式列出资源文件,因此它们没有 DependentUpon 元数据来指定如何命名生成的 .resources 文件。 如果 EmbeddedResourceUseDependentUponConvention 设置为 true(默认值),则 MSBuild 将查找并置的源文件,并从该文件中提取命名空间和类名。 如果将 EmbeddedResourceUseDependentUponConvention 设置为 false,则 MSBuild 将根据之前的行为生成清单名称,将 RootNamespace 和相对文件路径组合在一起。

在大多数情况下,开发人员不需要执行任何操作,应用应可以继续工作。 但是,如果此更改造成应用中断运行,你可以:

  • 将代码更改为需要新的清单名称。

  • 在项目文件中将 EmbeddedResourceUseDependentUponConvention 设置为 false,以选择退出新命名约定。

    <PropertyGroup>
      <EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
    </PropertyGroup>
    

类别

MSBuild

受影响的 API

不适用


网络

HttpRequestMessage.Version 的默认值已更改为 1.1

System.Net.Http.HttpRequestMessage.Version 属性的默认值已从 2.0 更改为 1.1。

引入的版本

3.0

更改描述

在 .NET Core 1.0 至 2.0 中,System.Net.Http.HttpRequestMessage.Version 属性的默认值为 1.1。 从 .NET Core 2.1 开始,该值已更改为 2.1。

从 .NET Core 3.0 开始,System.Net.Http.HttpRequestMessage.Version 属性返回的默认版本号再次为 1.1。

如果代码依赖于 System.Net.Http.HttpRequestMessage.Version 属性,则返回默认值 2.0,以更新代码。

类别

网络

受影响的 API


另请参阅