培训
.NET Core 3.0 中的中断性变更
若要迁移到 3.0 版 .NET Core、ASP.NET Core 或 EF Core,本文中列出的中断性变更可能会影响到你的应用。
- 已删除过时防伪、CORS、诊断、MVC 和路由 API
- 已删除“Pubternal”API
- 身份验证:Google+ 弃用
- 身份验证:已删除 HttpContext.Authentication 属性
- 身份验证:已替换 Newtonsoft.json 类型
- 身份验证:已更改 OAuthHandler ExchangeCodeAsync 签名
- 授权:AddAuthorization 重载已移到不同的程序集
- 授权:已从 AuthorizationFilterContext.Filters 中删除 IAllowAnonymous
- 授权:IAuthorizationPolicyProvider 实现需要新方法
- 缓存:已删除 CompactOnMemoryPressure 属性
- 缓存:Microsoft.Extensions.Caching.SqlServer 使用新的 SqlClient 包
- 缓存:ResponseCaching“Pubternal”类型已更改为内部类型
- 数据保护:DataProtection.Blobs 使用新的 Azure 存储 API
- 托管:已从 Windows 托管捆绑包中删除 AspNetCoreModule V1
- 托管:通用主机限制 Startup 构造函数注入
- 托管:已为 IIS 进程外应用启用 HTTPS 重定向
- 托管:已替换 IHostingEnvironment 和 IApplicationLifetime 类型
- 托管:已从 WebHostBuilder 依赖项中删除 ObjectPoolProvider
- HTTP:已删除 DefaultHttpContext 扩展性
- HTTP:HeaderNames 字段已更改为静态只读
- HTTP:响应正文基础结构更改
- HTTP:已更改某些 Cookie SameSite 默认值
- HTTP:已默认禁用同步 IO
- 标识:已删除 AddDefaultUI 方法重载
- 标识:UI 启动版本更改
- 标识:对于未经身份验证的标识,SignInAsync 会引发异常
- 标识:SignInManager 构造函数接受新参数
- 标识:UI 使用静态 Web 资产功能
- Kestrel:已删除连接适配器
- Kestrel:已删除空 HTTPS 程序集
- Kestrel:请求尾部标头已移到新集合
- Kestrel:传输抽象层更改
- 本地化:API 已标记为已过时
- 日志记录:已将 DebugLogger 类设为内部类
- MVC:已删除控制器操作 Async 后缀
- MVC:JsonResult 已移至 Microsoft.AspNetCore.Mvc.Core
- MVC:已弃用预编译工具
- MVC:类型已更改为内部
- MVC:已删除 Web API 兼容性填充码
- Razor:已删除 RazorTemplateEngine API
- Razor:运行时编译已移到包
- 会话状态:已删除过时的 API
- 共享框架:已从 Microsoft.AspNetCore.App 中删除程序集
- 共享框架:已删除 Microsoft.AspNetCore.All
- SignalR:已替换 HandshakeProtocol.SuccessHandshakeData
- SignalR:已删除 HubConnection 方法
- SignalR:已更改 HubConnectionContext 构造函数
- SignalR:JavaScript 客户端包名称更改
- SignalR:过时的 API
- SPA:SpaServices 和 NodeServices 已标记为过时
- SPA:SpaServices 和 NodeServices 控制台记录器回退默认更改
- 目标框架:不支持 .NET Framework
删除了 ASP.NET Core 2.2 中的过时成员和兼容性开关。
3.0
随着时间的推移,API 图面会得到改进。
针对 .NET Core 2.2 时,请遵循过时生成消息中的指导来改为采用新 API。
ASP.NET Core
以下类型和成员标记为对 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
方法
Microsoft.AspNetCore.Mvc.LocalRedirectResult.ExecuteResult(ActionContext)
Microsoft.AspNetCore.Mvc.RedirectResult.ExecuteResult(ActionContext)
Microsoft.AspNetCore.Mvc.RedirectToActionResult.ExecuteResult(ActionContext)
Microsoft.AspNetCore.Mvc.RedirectToPageResult.ExecuteResult(ActionContext)
Microsoft.AspNetCore.Mvc.RedirectToRouteResult.ExecuteResult(ActionContext)
Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext,IValueProvider,ParameterDescriptor)
- Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext,IValueProvider,ParameterDescriptor,Object)
为了更好地维护 ASP.NET Core 面向公众的 API,*.Internal
命名空间中的大多数类型(称为 "pubternal" API)已成为真正的内部类型。 这些命名空间中的成员永远不会作为面向公众的 API 得到支持。 API 可能在次要版本中中断(这种情况经常会发生)。 在更新到 ASP.NET Core 3.0 时,依赖于这些 API 的代码会中断。
有关详细信息,请参阅 dotnet/aspnetcore#4932 和 dotnet/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
名称中具有 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 早在 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 的外部更改。
针对 Microsoft.Owin
3.1.0 和更高版本,本文概述了临时的缓解措施。 应用应通过缓解措施来完成测试,以检查数据格式的更改。 计划发布 Microsoft.Owin
4.0.1,并提供一个修补程序。 使用任何较低版本的应用都应更新到版本 4.0.1。
包含 ASP.NET Web Form 和MVC 的 Owin的缓解措施可应用于 ASP.NET Core 1.x。 未计划 NuGet 包修补程序,因为 1.x 已处于生命周期结束状态。
对于 Microsoft.AspNetCore.Authentication.Google
版本 2.x,请将对 Startup.ConfigureServices
中 AddGoogle
的现有调用替换为以下代码:
.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 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
Microsoft.AspNetCore.Authentication.Google
已删除 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
- Microsoft.AspNetCore.Http.Authentication.AuthenticateInfo
- Microsoft.AspNetCore.Http.Authentication.AuthenticationManager
- Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties
- Microsoft.AspNetCore.Http.Features.Authentication.AuthenticateContext
- Microsoft.AspNetCore.Http.Features.Authentication.ChallengeBehavior
- Microsoft.AspNetCore.Http.Features.Authentication.ChallengeContext
- Microsoft.AspNetCore.Http.Features.Authentication.DescribeSchemesContext
- Microsoft.AspNetCore.Http.Features.Authentication.IAuthenticationHandler
- Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature.Handler
- Microsoft.AspNetCore.Http.Features.Authentication.SignInContext
- Microsoft.AspNetCore.Http.Features.Authentication.SignOutContext
- Microsoft.AspNetCore.Http.HttpContext.Authentication
在 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
。
以下列表概述了已知更改:
- ClaimAction.Run(JObject, ClaimsIdentity, String) 变为
ClaimAction.Run(JsonElement userData, ClaimsIdentity identity, string issuer)
。ClaimAction
的所有派生的实现都受到类似的影响。 - ClaimActionCollectionMapExtensions.MapCustomJson(ClaimActionCollection, String, Func<JObject,String>) 变为
MapCustomJson(this ClaimActionCollection collection, string claimType, Func<JsonElement, string> resolver)
- ClaimActionCollectionMapExtensions.MapCustomJson(ClaimActionCollection, String, String, Func<JObject,String>) 变为
MapCustomJson(this ClaimActionCollection collection, string claimType, string valueType, Func<JsonElement, string> resolver)
- OAuthCreatingTicketContext 已移除一个旧构造函数,另一个将
JObject
替换为JsonElement
。 已更新User
属性和RunClaimActions
方法以使其匹配。 - Success(JObject) 现在接受类型为
JsonDocument
而非JObject
的参数。 已更新Response
属性以使其匹配。OAuthTokenResponse
现在可处置,并将由OAuthHandler
处置。 替代ExchangeCodeAsync
的派生的 OAuth 实现无需处置JsonDocument
或OAuthTokenResponse
。 - UserInformationReceivedContext.User 从
JObject
更改为JsonDocument
。 - TwitterCreatingTicketContext.User 从
JObject
更改为JsonElement
。 - TwitterHandler.CreateTicketAsync(ClaimsIdentity,AuthenticationProperties,AccessToken,JObject) 的最后一个参数从
JObject
更改为JsonElement
。 替换方法为 TwitterHandler.CreateTicketAsync(ClaimsIdentity, AuthenticationProperties, AccessToken, JsonElement)。
ASP.NET Core
- Microsoft.AspNetCore.Authentication.Facebook
- Microsoft.AspNetCore.Authentication.Google
- Microsoft.AspNetCore.Authentication.MicrosoftAccount
- Microsoft.AspNetCore.Authentication.OAuth
- Microsoft.AspNetCore.Authentication.OpenIdConnect
- Microsoft.AspNetCore.Authentication.Twitter
在 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
code
和 redirectUri
字符串作为单独的参数传递。
Code
和 RedirectUri
是 OAuthCodeExchangeContext
上的属性,可通过 OAuthCodeExchangeContext
构造函数进行设置。 新的 OAuthCodeExchangeContext
类型是传递到 OAuthHandler.ExchangeCodeAsync
的唯一参数。
此更改允许以非中断方式提供其他参数。 无需创建新的 ExchangeCodeAsync
重载。
使用适当的 code
和 redirectUri
值构造 OAuthCodeExchangeContext
。 必须提供 AuthenticationProperties 实例。 此单个 OAuthCodeExchangeContext
实例可传递到 OAuthHandler.ExchangeCodeAsync
而不是多个参数。
ASP.NET Core
OAuthHandler<TOptions>.ExchangeCodeAsync(String, String)
用于驻留在 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
从 ASP.NET Core 3.0 起,MVC 不会为在控制器和操作方法上发现的 [AllowAnonymous] 属性添加 AllowAnonymousFilters。 此更改针对 AuthorizeAttribute 派生在本地进行处理,但对于 IAsyncAuthorizationFilter 和 IAuthorizationFilter 实现来说是一个重大变更。 包装在 [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
无
在 ASP.NET Core 3.0 中,已将一个新 GetFallbackPolicyAsync
方法添加到 IAuthorizationPolicyProvider
。 当未指定策略时,授权中间件会使用此回退策略。
有关详细信息,请参阅 dotnet/aspnetcore#9759。
3.0
IAuthorizationPolicyProvider
的实现不需要 GetFallbackPolicyAsync
方法。
IAuthorizationPolicyProvider
的实现需要 GetFallbackPolicyAsync
方法。
如果未指定策略,则新 AuthorizationMiddleware
需要使用新方法。
将 GetFallbackPolicyAsync
方法添加到 IAuthorizationPolicyProvider
的实现。
ASP.NET Core
Microsoft.AspNetCore.Authorization.IAuthorizationPolicyProvider
ASP.NET Core 3.0 版本已删除过时的 MemoryCacheOptions API。
此更改是对 aspnet/Caching#221 的后续补充。 有关讨论,请参阅 dotnet/extensions#1062。
3.0
MemoryCacheOptions.CompactOnMemoryPressure
属性可用。
MemoryCacheOptions.CompactOnMemoryPressure
属性已被删除。
自动压缩缓存会引起问题。 若要避免意外行为,只应在需要时压缩缓存。
若要压缩缓存,请向下转换到 MemoryCache
并在需要时调用 Compact
。
ASP.NET Core
MemoryCacheOptions.CompactOnMemoryPressure
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
无
在 ASP.NET Core 3.0 中,ResponseCaching
中的“pubternal”类型已更改为 internal
。
此外,IResponseCachingPolicyProvider
和 IResponseCachingKeyProvider
的默认实现不再作为 AddResponseCaching
方法的一部分添加到服务。
在 ASP.NET Core 中,“pubternal”类型声明为 public
,但驻留在后缀为 .Internal
的命名空间中。 尽管这些类型为 public,但它们没有支持策略,可能会发生中断性变更。 遗憾的是,经常会意外使用这些类型,导致对这些项目做出中断性变更,并使维护框架的能力受到限制。
3.0
这些类型公开可见,但不受支持。
这些类型现在为 internal
。
internal
范围更好地反映了不受支持的策略。
复制应用或库使用的类型。
ASP.NET Core
Microsoft.AspNetCore.ResponseCaching.Internal.CachedResponse
Microsoft.AspNetCore.ResponseCaching.Internal.CachedVaryByRules
Microsoft.AspNetCore.ResponseCaching.Internal.IResponseCache
Microsoft.AspNetCore.ResponseCaching.Internal.IResponseCacheEntry
Microsoft.AspNetCore.ResponseCaching.Internal.IResponseCachingKeyProvider
Microsoft.AspNetCore.ResponseCaching.Internal.IResponseCachingPolicyProvider
Microsoft.AspNetCore.ResponseCaching.Internal.MemoryResponseCache
Microsoft.AspNetCore.ResponseCaching.Internal.ResponseCachingContext
Microsoft.AspNetCore.ResponseCaching.Internal.ResponseCachingKeyProvider
Microsoft.AspNetCore.ResponseCaching.Internal.ResponseCachingPolicyProvider
- Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware.ResponseCachingMiddleware(RequestDelegate, IOptions<ResponseCachingOptions>, ILoggerFactory, IResponseCachingPolicyProvider, IResponseCache, IResponseCachingKeyProvider)
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.Storage 或 Microsoft.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
无
从 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
无
通用主机支持的 Startup
类构造函数注入的唯一类型为 IHostEnvironment
、IWebHostEnvironment
和 IConfiguration
。 使用 WebHost
的应用不受影响。
在低于 ASP.NET Core 3.0 的版本中,构造函数注入可用于 Startup
类的构造函数中的任意类型。 在 ASP.NET Core 3.0 中,Web 堆栈将重新平台化到通用主机库上。 可以在模板的 Program .cs 文件中查看更改:
ASP.NET Core 2.x:
ASP.NET Core 3.0:
Host
使用一个依赖关系注入 (DI) 容器生成应用。 WebHost
使用两个容器:一个用于主机,另一个用于应用。 因此,Startup
构造函数不再支持自定义服务注入。 只能注入 IHostEnvironment
、IWebHostEnvironment
和 IConfiguration
。 此更改可防止出现 DI 问题,例如重复创建单一实例服务。
3.0
此更改是将 Web 堆栈重新平台化到通用主机库的结果。
将服务注入 Startup.Configure
方法签名。 例如:
public void Configure(IApplicationBuilder app, IOptions<MyOptions> options)
ASP.NET Core
无
用于通过 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 中间件方法的支持,例如 UseHttpsRedirection 和 UseHsts。 启用 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_PORT
。 UseHttpsRedirection
在这些版本中也已更新,可同时理解新旧变量。 不会更新 ASP.NET Core 2.x。 因此,它会还原为默认禁用的先前行为。
已改进 ASP.NET Core 3.0 功能。
如果希望所有客户端都使用 HTTPS,则无需执行任何操作。 要允许部分客户端使用 HTTP,请执行以下步骤之一:
从项目的
Startup.Configure
方法中删除对UseHttpsRedirection
和UseHsts
的调用,然后重新部署应用。在 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
HttpsPolicyBuilderExtensions.UseHttpsRedirection(IApplicationBuilder)
引入了新类型以替换现有的 IHostingEnvironment
和 IApplicationLifetime
类型。
3.0
Microsoft.Extensions.Hosting
和 Microsoft.AspNetCore.Hosting
有两个不同的 IHostingEnvironment
和 IApplicationLifetime
类型。
旧类型已标记为过时,并已替换为新类型。
在 ASP.NET Core 2.1 中引入 Microsoft.Extensions.Hosting
时,从 Microsoft.AspNetCore.Hosting
复制了某些类型(如 IHostingEnvironment
和 IApplicationLifetime
)。 某些 ASP.NET Core 3.0 更改会导致应用包括 Microsoft.Extensions.Hosting
和 Microsoft.AspNetCore.Hosting
命名空间。 如果同时引用了两个命名空间,则使用这些重复类型会导致“引用不明确”编译器错误。
将旧类型的所有使用替换为新引入的类型,如下所示:
过时类型(警告):
- Microsoft.Extensions.Hosting.IHostingEnvironment
- Microsoft.AspNetCore.Hosting.IHostingEnvironment
- Microsoft.Extensions.Hosting.IApplicationLifetime
- Microsoft.AspNetCore.Hosting.IApplicationLifetime
- Microsoft.Extensions.Hosting.EnvironmentName
- Microsoft.AspNetCore.Hosting.EnvironmentName
新类型:
- Microsoft.Extensions.Hosting.IHostEnvironment
Microsoft.AspNetCore.Hosting.IWebHostEnvironment : IHostEnvironment
- Microsoft.Extensions.Hosting.IHostApplicationLifetime
- Microsoft.Extensions.Hosting.Environments
新的 IHostEnvironment
IsDevelopment
和 IsProduction
扩展方法位于 Microsoft.Extensions.Hosting
命名空间中。 可能需要将该命名空间添加到项目中。
ASP.NET Core
- Microsoft.AspNetCore.Hosting.EnvironmentName
- Microsoft.AspNetCore.Hosting.IApplicationLifetime
- Microsoft.AspNetCore.Hosting.IHostingEnvironment
- Microsoft.Extensions.Hosting.EnvironmentName
- Microsoft.Extensions.Hosting.IApplicationLifetime
- Microsoft.Extensions.Hosting.IHostingEnvironment
作为使 ASP.NET Core 更具成本效益计划的一部分,ObjectPoolProvider
已从主要依赖项集中删除。 依赖于 ObjectPoolProvider
的特定组件现在会自行添加。
有关讨论,请参阅 dotnet/aspnetcore#5944。
3.0
WebHostBuilder
默认在 DI 容器中提供 ObjectPoolProvider
。
WebHostBuilder
默认不再在 DI 容器中提供 ObjectPoolProvider
。
进行此更改是为了使 ASP.NET Core 更具成本效益。
如果组件需要 ObjectPoolProvider
,则需要通过 IServiceCollection
将其添加到依赖项。
ASP.NET Core
无
作为 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
Microsoft.AspNetCore.Http.DefaultHttpContext
从 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
Microsoft.Net.Http.Headers.HeaderNames
支持 HTTP 响应正文的基础结构已发生更改。 如果直接使用 HttpResponse
,则不需要进行任何代码更改。 如果要包装或替换 HttpResponse.Body
或访问 HttpContext.Features
,请进行进一步了解。
3.0
有三个 API 与 HTTP 响应正文关联:
IHttpResponseFeature.Body
IHttpSendFileFeature.SendFileAsync
IHttpBufferingFeature.DisableResponseBuffering
如果替换 HttpResponse.Body
,则它通过使用 StreamResponseBodyFeature
为所有预期的 API 提供默认实现,将整个 IHttpResponseBodyFeature
替换为给定流周围的包装器。 重新设置回原始流会还原此更改。
动机是将响应正文 API 合并为单一新功能接口。
使用之前在其中使用 IHttpResponseFeature.Body
、IHttpSendFileFeature
或 IHttpBufferingFeature
的 IHttpResponseBodyFeature
。
ASP.NET Core
- Microsoft.AspNetCore.Http.Features.IHttpBufferingFeature
- Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.Body
- Microsoft.AspNetCore.Http.Features.IHttpSendFileFeature
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.None
和 SameSiteMode.Lax
。
所有受影响的 API 都默认为 SameSiteMode.None
。
更改了默认值,使 SameSite
成为可选功能。
发出 cookie 的每个组件都需要决定 SameSite
是否适用于其方案。 检查受影响 API 的使用情况,并根据需要重新配置 SameSite
。
ASP.NET Core
从 ASP.NET Core 3.0 开始,默认将禁用同步服务器操作。
AllowSynchronousIO
是每台服务器中包含的一个选项,用于启用或禁用同步 IO API,如 HttpRequest.Body.Read
、HttpResponse.Body.Write
和 Stream.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.Read
、HttpResponse.Body.Write
和 Stream.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
从 ASP.NET Core 3.0 开始,IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder,UIFramework) 方法重载不再存在。
3.0
此更改是采用静态 Web 资产功能的结果。
调用 IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder) 而不是使用两个参数的重载。 如果使用的是 Bootstrap 3,还应将以下行添加到项目文件中的 <PropertyGroup>
元素:
<IdentityUIFrameworkVersion>Bootstrap3</IdentityUIFrameworkVersion>
ASP.NET Core
IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder,UIFramework)
从 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
无
默认情况下,SignInAsync
会为其中 IsAuthenticated
为 false
的主体/标识引发异常。
3.0
SignInAsync
接受任何主体/标识,包括其中 IsAuthenticated
为 false
的标识。
默认情况下,SignInAsync
会为其中 IsAuthenticated
为 false
的主体/标识引发异常。 有一个新的标志可禁止显示此行为,但默认行为已更改。
旧行为是有问题的,因为在默认情况下,[Authorize]
/ RequireAuthenticatedUser()
拒绝了这些主体。
在 ASP.NET Core 3.0 预览版 6 中,AuthenticationOptions
上有 RequireAuthenticatedSignIn
标记,默认为 true
。 将此标志设置为 false
以还原旧行为。
ASP.NET Core
无
从 ASP.NET Core 3.0 开始,新的 IUserConfirmation<TUser>
参数添加到了 SignInManager
构造函数中。 有关详细信息,请参阅 dotnet/aspnetcore#8356。
3.0
更改的动机是为了添加对标识中的新电子邮件/确认流的支持。
如果手动构造 SignInManager
,请提供 IUserConfirmation
的实现,或从依赖项注入获取一个实现来提供。
ASP.NET Core
ASP.NET Core 3.0 引入了静态 Web 资产功能,标识 UI 已采用此功能。
由于标识 UI 采用静态 Web 资产功能,因此:
- 可通过使用项目文件中的
IdentityUIFrameworkVersion
属性来完成框架选择。 - Bootstrap 4 是标识 UI 的默认 UI 框架。 Bootstrap 3 的生命周期已经结束,应考虑迁移到受支持的版本。
3.0
标识 UI 的默认 UI 框架为 Bootstrap 3。 可使用 Startup.ConfigureServices
中 AddDefaultUI
方法调用的参数配置 UI 框架。
标识 UI 的默认 UI 框架为 Bootstrap 4。 UI 框架必须在项目文件中进行配置,而不是在 AddDefaultUI
方法调用中配置。
采用静态 Web 资产功能要求 UI 框架配置迁移到 MSBuild。 要在哪个框架上进行嵌入的决策是生成时决策,而非运行时决策。
查看站点 UI,以确保新的 Bootstrap 4 组件兼容。 如有必要,请使用 IdentityUIFrameworkVersion
MSBuild 属性还原为 Bootstrap 3。 将属性添加到项目文件中的 <PropertyGroup>
元素:
<IdentityUIFrameworkVersion>Bootstrap3</IdentityUIFrameworkVersion>
ASP.NET Core
IdentityBuilderUIExtensions.AddDefaultUI(IdentityBuilder, UIFramework)
作为将“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
Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter
已删除程序集 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
无
在以前的版本中,当读取请求正文直到结尾时,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
作为远离“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
库最常用的功能。 - 现在提供传输选项
NoDelay
(LibuvTransportOptions
和SocketTransportOptions
)。 SchedulingMode
不再可用。
ASP.NET Core 3.0 已从“pubternal”API 移出。
ASP.NET Core
无
ResourceManagerWithCultureStringLocalizer 类和 WithCulture 接口成员通常是造成本地化用户混淆的原因,尤其是在创建自己的 IStringLocalizer
实现时。 这些项给用户留下了 IStringLocalizer
实例“按语言、按资源”的印象。 实际上,实例应该仅“按资源”。 搜索的语言由 CultureInfo.CurrentUICulture
在执行时确定。 为了消除混淆来源,这些 API 在 ASP.NET Core 3.0 中被标记为过时。 将从未来版本中删除这些 API。
有关上下文,请参阅 dotnet/aspnetcore#3324。 有关讨论,请参阅 dotnet/aspnetcore#7756。
3.0
方法未标记为 Obsolete
。
方法被标记为 Obsolete
。
API 表示一个不推荐使用的用例。 本地化设计存在混淆。
建议改用 ResourceManagerStringLocalizer
。 允许 CurrentCulture
设置区域性。 如果没有这个选项,请创建并使用 ResourceManagerWithCultureStringLocalizer 的副本。
ASP.NET Core
Microsoft.Extensions.Localization.ResourceManagerWithCultureStringLocalizer
Microsoft.Extensions.Localization.ResourceManagerStringLocalizer.WithCulture
在 ASP.NET Core 3.0 之前,DebugLogger
的访问修饰符为 public
。 在 ASP.NET Core 3.0 中,访问修饰符更改为 internal
。
3.0
正在进行更改以便:
- 强制执行与其他记录器(如
ConsoleLogger
)实现的一致性。 - 减少 API 图面。
使用 AddDebug ILoggingBuilder
扩展方法来启用调试日志记录。 如果需要手动注册服务,DebugLoggerProvider 也仍为 public
。
ASP.NET Core
Microsoft.Extensions.Logging.Debug.DebugLogger
作为寻址 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
无
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
Microsoft.AspNetCore.Mvc.JsonResult
在 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
无
在 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
此更改包括以下命名空间中的类型:
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
从 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
Microsoft.AspNetCore.Mvc.WebApiCompatShim
已删除 RazorTemplateEngine
API,该内容已替换为 Microsoft.AspNetCore.Razor.Language.RazorProjectEngine
。
有关讨论,请参阅 GitHub 问题 dotnet/aspnetcore#25215。
3.0
可创建模板引擎并将其用于分析和生成 Razor 文件的代码。
可创建 RazorProjectEngine
,使其提供与 RazorTemplateEngine
相同类型的信息,以分析和生成 Razor 文件的代码。 RazorProjectEngine
也可提供额外的配置级别。
RazorTemplateEngine
与现有实现过于紧密耦合。 在尝试正确配置 Razor 分析/生成管道时,这种紧密耦合会导致更多问题。
请使用 RazorProjectEngine
,而不是 RazorTemplateEngine
。 请考虑以下示例。
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
});
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
RazorTemplateEngine
RazorTemplateEngineOptions
支持 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 文件进行运行时编译或重新编译的应用应执行以下步骤:
添加对
Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
包的引用。更新项目的
Startup.ConfigureServices
方法以包含对AddRazorRuntimeCompilation
的调用。 例如:services.AddMvc() .AddRazorRuntimeCompilation();
ASP.NET Core
Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions
已删除用于配置会话 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
- Microsoft.AspNetCore.Builder.SessionOptions.CookieDomain
- Microsoft.AspNetCore.Builder.SessionOptions.CookieHttpOnly
- Microsoft.AspNetCore.Builder.SessionOptions.CookieName
- Microsoft.AspNetCore.Builder.SessionOptions.CookiePath
- Microsoft.AspNetCore.Builder.SessionOptions.CookieSecure
从 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 包的形式提供:- Entity Framework Core
- 提供第三方集成的 API
- 实验性功能
- 包含无法满足共享框架中的要求的依赖项的 API
- 用于保留对 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
从 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
无
已删除 HandshakeProtocol.SuccessHandshakeData 字段,并将其替换为一个 Helper 方法,该方法根据特定 IHubProtocol
生成成功的握手响应。
3.0
HandshakeProtocol.SuccessHandshakeData
是 public static ReadOnlyMemory<byte>
字段。
HandshakeProtocol.SuccessHandshakeData
已被 static
GetSuccessfulHandshake(IHubProtocol protocol)
方法替换,该方法根据指定的协议返回 ReadOnlyMemory<byte>
。
握手响应中添加了其他字段,这些字段是非常量,并会根据所选协议的不同而变化。
无。 此类型不适用于从用户代码使用。 它是 public
类型,因此可以在 SignalR 服务器和客户端之间共享。 它还可以由以 .NET 编写的客户 SignalR 客户端使用。 SignalR 用户不应受此更改的影响。
ASP.NET Core
HandshakeProtocol.SuccessHandshakeData
已从 SignalR HubConnection
API 中删除了 ResetSendPing
和 ResetTimeout
方法。 这些方法最初仅供内部使用,但已在 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
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
- HubConnectionContext(ConnectionContext, TimeSpan, ILoggerFactory)
- HubConnectionContext(ConnectionContext, TimeSpan, ILoggerFactory, TimeSpan)
在 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
无
在 ASP.NET Core 3.0 中,方法 UseConnections
和 UseSignalR
以及类 ConnectionsRouteBuilder
和 HubRouteBuilder
被标记为过时。
3.0
SignalR 中心路由是使用 UseSignalR
或 UseConnections
配置的。
配置路由的旧方法已弃用,并已替换为终结点路由。
正在将中间件移动到新的终结点路由系统。 添加中间件的旧方法即将过时。
将 UseSignalR
替换为 UseEndpoints
:
旧代码:
app.UseSignalR(routes =>
{
routes.MapHub<SomeHub>("/path");
});
新代码:
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<SomeHub>("/path");
});
ASP.NET Core
- Microsoft.AspNetCore.Builder.ConnectionsAppBuilderExtensions.UseConnections(IApplicationBuilder, Action<ConnectionsRouteBuilder>)
- Microsoft.AspNetCore.Builder.SignalRAppBuilderExtensions.UseSignalR(IApplicationBuilder, Action<HubRouteBuilder>)
- Microsoft.AspNetCore.Http.Connections.ConnectionsRouteBuilder
- Microsoft.AspNetCore.SignalR.HubRouteBuilder
自 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
Microsoft.AspNetCore.NodeServices.HostingModels.INodeInstance
Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationException
Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationInfo
Microsoft.AspNetCore.NodeServices.HostingModels.NodeServicesOptionsExtensions
Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance
Microsoft.AspNetCore.SpaServices.Prerendering.ISpaPrerenderer
Microsoft.AspNetCore.SpaServices.Prerendering.ISpaPrerendererBuilder
Microsoft.AspNetCore.SpaServices.Prerendering.JavaScriptModuleExport
Microsoft.AspNetCore.SpaServices.Prerendering.PrerenderTagHelper
Microsoft.AspNetCore.SpaServices.Prerendering.RenderToStringResult
Microsoft.AspNetCore.SpaServices.Webpack.WebpackDevMiddlewareOptions
Microsoft.Extensions.DependencyInjection.NodeServicesServiceCollectionExtensions
Microsoft.Extensions.DependencyInjection.PrerenderingServiceCollectionExtensions
除非配置了日志记录,否则 Microsoft.AspNetCore.SpaServices 和 Microsoft.AspNetCore.NodeServices 不会显示控制台日志。
3.0
Microsoft.AspNetCore.SpaServices
和 Microsoft.AspNetCore.NodeServices
用于在未配置日志记录时自动创建控制台记录器。
除非配置了日志记录,否则 Microsoft.AspNetCore.SpaServices
和 Microsoft.AspNetCore.NodeServices
不会显示控制台日志。
需要与其他 ASP.NET Core 包实现日志记录的方式保持一致。
如果需要旧行为,若要配置控制台日志记录,请将 services.AddLogging(builder => builder.AddConsole())
添加到 Setup.ConfigureServices
方法。
ASP.NET Core
无
从 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 现在报告产品版本而不是文件版本
- 自定义 EncoderFallbackBuffer 实例无法递归回退
- 浮点格式设置和分析行为变更
- 浮点分析操作不再失败或引发 OverflowException
- InvalidAsynchronousStateException 已移到另一个程序集
- 替换格式错误的 UTF-8 字节序列将遵循 Unicode 准则
- TypeDescriptionProviderAttribute 已移到另一个程序集
- ZipArchiveEntry 不再处理条目大小不一致的存档
- FieldInfo.SetValue 将对静态、仅初始化字段引发异常
- 将 GroupCollection 传递到采用 IEnumerable<T> 的扩展方法需要消除歧义
返回 .NET Core 中的版本的很多 API 现在返回的是产品版本,而不是文件版本。
在 .NET Core 2.2 及更低版本中,Environment.Version 和 RuntimeInformation.FrameworkDescription 等方法以及 .NET Core 程序集的“文件属性”对话框反映的都是文件版本。 自 .NET Core 3.0 起,它们反映的是产品版本。
下图展示了由“Windows 资源管理器”文件属性对话框显示的 .NET Core 2.2(左侧)与 .NET Core 3.0(右侧)的 System.Runtime.dll 程序集版本信息区别 。
3.0
无。 此更改会使版本检测变得直观而非退化。
Core .NET 库
自定义 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
大多数开发人员都不需要执行任何操作。
如果应用程序使用自定义 EncoderFallback 和 EncoderFallbackBuffer 类,请确保 EncoderFallbackBuffer.Fallback 的实现使用格式正确的 UTF-16 数据(该数据在运行时第一次调用 Fallback 方法时可直接转换为目标编码)填充回退缓冲区。
Core .NET 库
浮点分析和格式设置行为(由 Double 和 Single 类型实现)现符合 IEEE 标准。 这可确保 .NET 中浮点类型的行为与符合 IEEE 标准的语言的行为一致。 例如,double.Parse("SomeLiteral")
应始终与 C# 为 double x = SomeLiteral
生成的结果匹配。
在 .NET Core 2.2 及更低版本中,通过 Double.ToString 和 Single.ToString 进行格式设置的行为,以及使用 Double.Parse、Double.TryParse、Single.Parse 和 Single.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 库
浮点分析方法在分析数值超出 Single 或 Double 浮点类型范围的字符串时,不再引发 OverflowException 或返回 false
。
在 .NET Core2.2 和早期版本中,Double.Parse 和 Single.Parse 方法对超出其各自类型范围的值会引发 OverflowException。 对于超出范围的数值的字符串表示形式,Double.TryParse 和 Single.TryParse 方法返回 false
。
从 .NET Core 3.0 开始,分析超出范围的数值字符串时,Double.Parse、Double.TryParse、Single.Parse 和 Single.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.IsInfinity 或 Single.IsInfinity 是否为true
。代码假设浮点值不是
Infinity
。 在这种情况下,应添加必要的代码来检查PositiveInfinity
和NegativeInfinity
的浮点值。
Core .NET 库
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 库
无。
UTF8Encoding 类在字节到字符转码操作期间遇到格式错误的 UTF-8 字节序列时,它将在输出字符串中用“�”(U+FFFD 替换字符)替换该序列。 .NET Core 3.0 与以前版本的 .NET Core 和 .NET Framework 的不同之处在于,在转码操作期间按照 Unicode 最佳做法执行此替换。
这是在整个 .NET 中改进 UTF-8 处理的较大工作量(包括通过新的 System.Text.Unicode.Utf8 和 System.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 库
TypeDescriptionProviderAttribute 类已移动。
在 .NET Core 2.2 及更低版本中,TypeDescriptionProviderAttribute 位于 System.ComponentModel.TypeConverter 程序集中。
而自 .NET Core 3.0 起,它位于 System.ObjectModel 程序集中。
3.0
此更改仅影响这样的应用程序,它们通过调用 Assembly.GetType 等方法或调用假设类型位于特定程序集中的 Activator.CreateInstance 的重载,使用反射过程来加载 TypeDescriptionProviderAttribute 类型。 若是如此,应更新在方法调用反射的程序集,以反射出类型的新程序集位置。
Windows 窗体
无。
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 库
- ZipArchiveEntry.Open()
- ZipFileExtensions.ExtractToDirectory
- ZipFileExtensions.ExtractToFile
- ZipFile.ExtractToDirectory
从 .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 库
- FieldInfo.SetValue(Object, Object)
- FieldInfo.SetValue(Object, Object, BindingFlags, Binder, CultureInfo)
调用在 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 库
任何接受 IEnumerable<T> 的扩展方法都会受到影响。 例如:
- System.Collections.Immutable.ImmutableArray.ToImmutableArray<TSource>(IEnumerable<TSource>)
- System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary
- System.Collections.Immutable.ImmutableHashSet.ToImmutableHashSet
- System.Collections.Immutable.ImmutableList.ToImmutableList<TSource>(IEnumerable<TSource>)
- System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary
- System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet
- System.Data.DataTableExtensions.CopyToDataTable
- 大多数
System.Linq.Enumerable
方法,例如 System.Linq.Enumerable.Count - System.Linq.ParallelEnumerable.AsParallel
- System.Linq.Queryable.AsQueryable
- Linux 不再支持 BEGIN TRUSTED CERTIFICATE 语法
- EnvelopedCms 默认为 AES-256 加密
- RSAOpenSsl 密钥生成的最小大小已增加
- .NET Core 3.0 倾向于使用 OpenSSL 1.1.x 而不是 OpenSSL 1.0.x
- CryptoStream.Dispose 仅在写入时转换最终块
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 CERTIFICATE
和 BEGIN 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
密码
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();
密码
在 Linux 上生成新 RSA 密钥的最小大小已从 384 位提高到 512 位。
自 .NET Core 3.0 起,Linux 上 RSA.CreateRSAOpenSsl 和 RSACryptoServiceProvider 中 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 位作为新生成的密钥的最小大小。
密码
跨多个 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 互操作的 IntPtr 和 SafeHandle 类型倾向于与 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 互操作的 IntPtr 和 SafeHandle 类型倾向于与 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 加密类型中的 IntPtr 或 SafeHandle 值直接用于 OpenSSL 的库或应用程序都应当将其使用的库的版本与新的 SafeEvpPKeyHandle.OpenSslVersion 属性进行比较,以确保指针兼容。
密码
- SafeEvpPKeyHandle
- RSAOpenSsl(IntPtr)
- RSAOpenSsl(SafeEvpPKeyHandle)
- RSAOpenSsl.DuplicateKeyHandle()
- DSAOpenSsl(IntPtr)
- DSAOpenSsl(SafeEvpPKeyHandle)
- DSAOpenSsl.DuplicateKeyHandle()
- ECDsaOpenSsl(IntPtr)
- ECDsaOpenSsl(SafeEvpPKeyHandle)
- ECDsaOpenSsl.DuplicateKeyHandle()
- ECDiffieHellmanOpenSsl(IntPtr)
- ECDiffieHellmanOpenSsl(SafeEvpPKeyHandle)
- ECDiffieHellmanOpenSsl.DuplicateKeyHandle()
- X509Certificate.Handle
用于完成 CryptoStream
操作的 CryptoStream.Dispose 方法不再尝试在读取时转换最终块。
在以前的 .NET 版本中,如果用户在 Read 模式下使用 CryptoStream 时执行了不完整的读取操作,Dispose 方法可能会引发异常(例如,使用带有填充的 AES 时)。 引发异常是因为尝试转换最终块,但数据不完整。
在 .NET Core 3.0 及更高版本中,Dispose 不再尝试在读取时转换最终块,这会允许执行不完整的读取操作。
由于此更改,当取消网络操作后,将允许从加密流中进行不完整的读取操作,而无需捕获异常。
3.0
大多数应用都不会受到此更改的影响。
如果应用程序先前在读取不完整的情况下捕获到异常,你可以删除相应 catch
块。
如果应用在哈希方案中使用了最终块的转换,则可能需要确保在释放所有流之前先对其进行读取。
密码
.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 都会受到此变更的影响。
从 .NET Core 3.0 开始,默认情况下,MSBuild 会为资源文件生成不同的清单文件名。
3.0
在 .NET Core 3.0 之前,如果没有为项目文件中的 EmbeddedResource
项指定 LogicalName
、ManifestResourceName
或 DependentUpon
元数据,则 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
项上指定 LogicalName
、ManifestResourceName
或 DependentUpon
元数据,则此更改不会影响该资源文件。
此重大更改是在 .NET Core 项目中添加 EmbeddedResourceUseDependentUponConvention
属性时引入的。 默认情况下,不会在 .NET Core 项目文件中显式列出资源文件,因此它们没有 DependentUpon
元数据来指定如何命名生成的 .resources 文件。 如果 EmbeddedResourceUseDependentUponConvention
设置为 true
(默认值),则 MSBuild 将查找并置的源文件,并从该文件中提取命名空间和类名。 如果将 EmbeddedResourceUseDependentUponConvention
设置为 false
,则 MSBuild 将根据之前的行为生成清单名称,将 RootNamespace
和相对文件路径组合在一起。
在大多数情况下,开发人员不需要执行任何操作,应用应可以继续工作。 但是,如果此更改造成应用中断运行,你可以:
将代码更改为需要新的清单名称。
在项目文件中将
EmbeddedResourceUseDependentUponConvention
设置为false
,以选择退出新命名约定。<PropertyGroup> <EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention> </PropertyGroup>
MSBuild
不适用
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,以更新代码。
网络
.NET Core 3.0 引入了文本编辑器控件在将文本拖动到另一个控件时如何创建 System.Windows.DataObject 控件的更改。 更改禁用了自动转换,导致操作保留数据, DataFormats.Text 而不是 DataFormats.UnicodeText 将其 DataFormats.StringFormat转换为 。
.NET Core 3.0
Windows Presentation Foundation
从文本编辑器控件拖动文本时的数据类型 System.Windows.DataObject 为 DataFormats.StringFormat。
从文本编辑器控件拖动文本时打开 System.Windows.DataObject 的数据类型为 DataFormats.Text 或 DataFormats.UnicodeText。
此更改为行为更改。
这一变化是无意的。
此更改已在 .NET 7 中还原。 升级到 .NET 7 或更高版本。