migrate-dotnet9-to-dotnet10

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

.NET 9 → .NET 10 Migration

.NET 9 迁移至 .NET 10

Migrate a .NET 9 project or solution to .NET 10, systematically resolving all breaking changes. The outcome is a project targeting
net10.0
that builds cleanly, passes tests, and accounts for every behavioral, source-incompatible, and binary-incompatible change introduced in the .NET 10 release.
将.NET 9项目或解决方案迁移至.NET 10,系统地解决所有重大变更。最终目标是得到一个以
net10.0
为目标框架的项目,能够干净构建、通过测试,并适配.NET 10版本中引入的所有行为、源代码不兼容和二进制不兼容变更。

When to Use

适用场景

  • Upgrading
    TargetFramework
    from
    net9.0
    to
    net10.0
  • Resolving build errors or new warnings after updating the .NET 10 SDK
  • Adapting to behavioral changes in .NET 10 runtime, ASP.NET Core 10, or EF Core 10
  • Updating CI/CD pipelines, Dockerfiles, or deployment scripts for .NET 10
  • Migrating from the community
    System.Linq.Async
    package to the built-in
    System.Linq.AsyncEnumerable
  • TargetFramework
    net9.0
    升级至
    net10.0
  • 更新.NET 10 SDK后解决构建错误或新警告
  • 适配.NET 10运行时、ASP.NET Core 10或EF Core 10中的行为变更
  • 为.NET 10更新CI/CD流水线、Dockerfile或部署脚本
  • 从社区
    System.Linq.Async
    包迁移至内置的
    System.Linq.AsyncEnumerable

When Not to Use

不适用场景

  • The project already targets
    net10.0
    and builds cleanly — migration is done
  • Upgrading from .NET 8 or earlier — use the
    migrate-dotnet8-to-dotnet9
    skill first to reach
    net9.0
    , then return to this skill for the
    net9.0
    net10.0
    migration
  • Migrating from .NET Framework — that is a separate, larger effort
  • Greenfield projects that start on .NET 10 (no migration needed)
  • 项目已以
    net10.0
    为目标框架且能干净构建——迁移已完成
  • 从.NET 8或更早版本升级——请先使用
    migrate-dotnet8-to-dotnet9
    工具升级至
    net9.0
    ,再使用本工具进行
    net9.0
    net10.0
    的迁移
  • 从.NET Framework迁移——这是独立的大型迁移工作
  • 全新.NET 10项目(无需迁移)

Inputs

输入项

InputRequiredDescription
Project or solution pathYesThe
.csproj
,
.sln
, or
.slnx
entry point to migrate
Build commandNoHow to build (e.g.,
dotnet build
, a repo build script). Auto-detect if not provided
Test commandNoHow to run tests (e.g.,
dotnet test
). Auto-detect if not provided
Project type hintsNoWhether the project uses ASP.NET Core, EF Core, WinForms, WPF, containers, etc. Auto-detect from PackageReferences and SDK attributes if not provided
输入项是否必填描述
项目或解决方案路径要迁移的
.csproj
.sln
.slnx
入口文件
构建命令构建方式(如
dotnet build
、仓库构建脚本)。未提供时自动检测
测试命令测试运行方式(如
dotnet test
)。未提供时自动检测
项目类型提示项目是否使用ASP.NET Core、EF Core、WinForms、WPF、容器等。未提供时从PackageReferences和SDK属性自动检测

Workflow

工作流程

Answer directly from the loaded reference documents. Do not search the filesystem or fetch web pages for breaking change information — the references contain the authoritative details. Focus on identifying which breaking changes apply and providing concrete fixes. Exception: If you suspect a security vulnerability (CVE) may apply to the project's dependencies, check for published security advisories — the reference documents may not cover post-publication CVEs.
Commit strategy: Commit at each logical boundary — after updating the TFM (Step 2), after resolving build errors (Step 3), after addressing behavioral changes (Step 4), and after updating infrastructure (Step 5). This keeps each commit focused and reviewable.
直接从加载的参考文档中获取答案。不要搜索文件系统或网页获取重大变更信息——参考文档包含权威细节。重点识别适用的重大变更并提供具体修复方案。例外情况:如果怀疑项目依赖项存在安全漏洞(CVE),请检查已发布的安全公告——参考文档可能未涵盖发布后的CVE。
提交策略:在每个逻辑阶段提交代码——更新TFM后(步骤2)、解决构建错误后(步骤3)、处理行为变更后(步骤4)、更新基础设施后(步骤5)。这样每个提交都聚焦明确,便于评审。

Step 1: Assess the project

步骤1:评估项目

  1. Identify how the project is built and tested. Look for build scripts,
    .sln
    /
    .slnx
    files, or individual
    .csproj
    files.
  2. Run
    dotnet --version
    to confirm the .NET 10 SDK is installed. If it is not, stop and inform the user.
  3. Determine which technology areas the project uses by examining:
    • SDK attribute:
      Microsoft.NET.Sdk.Web
      → ASP.NET Core;
      Microsoft.NET.Sdk.WindowsDesktop
      with
      <UseWPF>
      or
      <UseWindowsForms>
      → WPF/WinForms
    • PackageReferences:
      Microsoft.EntityFrameworkCore.*
      → EF Core;
      Microsoft.Data.Sqlite
      → Sqlite;
      Microsoft.Extensions.Hosting
      → Generic Host / BackgroundService
    • Dockerfile presence → Container changes relevant
    • P/Invoke or native interop usage → Interop changes relevant
    • System.Linq.Async
      package reference
      → AsyncEnumerable migration needed
    • System.Text.Json
      usage with polymorphism
      → Serialization changes relevant
  4. Record which reference documents are relevant (see the reference loading table in Step 3).
  5. Do a clean build (
    dotnet build --no-incremental
    or delete
    bin
    /
    obj
    ) on the current
    net9.0
    target to establish a clean baseline. Record any pre-existing warnings.
  1. 确定项目的构建和测试方式。查找构建脚本、
    .sln
    /
    .slnx
    文件或单个
    .csproj
    文件。
  2. 运行
    dotnet --version
    确认已安装.NET 10 SDK。若未安装,停止操作并告知用户。
  3. 通过检查以下内容确定项目使用的技术领域:
    • SDK属性
      Microsoft.NET.Sdk.Web
      → ASP.NET Core;
      Microsoft.NET.Sdk.WindowsDesktop
      搭配
      <UseWPF>
      <UseWindowsForms>
      → WPF/WinForms
    • PackageReferences
      Microsoft.EntityFrameworkCore.*
      → EF Core;
      Microsoft.Data.Sqlite
      → Sqlite;
      Microsoft.Extensions.Hosting
      → 通用宿主/BackgroundService
    • Dockerfile存在性 → 需关注容器相关变更
    • P/Invoke或本地互操作使用情况 → 需关注互操作变更
    • System.Linq.Async
      包引用
      → 需要迁移至AsyncEnumerable
    • 使用
      System.Text.Json
      的多态场景
      → 需关注序列化变更
  4. 记录相关的参考文档(见步骤3中的参考文档加载表)。
  5. 对当前
    net9.0
    目标框架执行干净构建
    dotnet build --no-incremental
    或删除
    bin
    /
    obj
    目录),建立干净基线。记录所有预先存在的警告。

Step 2: Update the Target Framework

步骤2:更新目标框架

  1. In each
    .csproj
    (or
    Directory.Build.props
    if centralized), change:
    xml
    <TargetFramework>net9.0</TargetFramework>
    to:
    xml
    <TargetFramework>net10.0</TargetFramework>
    For multi-targeted projects, add
    net10.0
    to
    <TargetFrameworks>
    or replace
    net9.0
    .
  2. Update all
    Microsoft.Extensions.*
    ,
    Microsoft.AspNetCore.*
    ,
    Microsoft.EntityFrameworkCore.*
    , and other Microsoft package references to their 10.0.x versions. If using Central Package Management (
    Directory.Packages.props
    ), update versions there.
  3. Run
    dotnet restore
    . Watch for:
    • NU1510: Direct references pruned by NuGet — the package may be included in the shared framework now. Remove the explicit
      <PackageReference>
      if so.
    • PackageReference without a version now raises an error — every
      <PackageReference>
      must have a
      Version
      (or use CPM).
    • NuGet auditing of transitive packages (
      dotnet restore
      now audits transitive deps) — review any new vulnerability warnings.
  4. Run a clean build. Collect all errors and new warnings. These will be addressed in Step 3.
  1. 在每个
    .csproj
    (或集中管理的
    Directory.Build.props
    )中,将:
    xml
    <TargetFramework>net9.0</TargetFramework>
    修改为:
    xml
    <TargetFramework>net10.0</TargetFramework>
    对于多目标框架项目,在
    <TargetFrameworks>
    中添加
    net10.0
    或替换
    net9.0
  2. 将所有
    Microsoft.Extensions.*
    Microsoft.AspNetCore.*
    Microsoft.EntityFrameworkCore.*
    及其他微软包引用更新至10.0.x版本。若使用中央包管理(
    Directory.Packages.props
    ),则在该文件中更新版本。
  3. 运行
    dotnet restore
    。注意以下情况:
    • NU1510:NuGet自动移除直接引用——该包现在可能已包含在共享框架中,若如此则移除显式的
      <PackageReference>
    • 无版本的PackageReference现在会引发错误——每个
      <PackageReference>
      必须指定
      Version
      (或使用CPM)。
    • NuGet会审核传递依赖包
      dotnet restore
      现在会审核传递依赖)——查看任何新的漏洞警告。
  4. 执行干净构建。收集所有错误和新警告,这些将在步骤3中处理。

Step 3: Resolve build errors and source-incompatible changes

步骤3:解决构建错误和源代码不兼容变更

Work through compilation errors and new warnings systematically. Load the appropriate reference documents based on the project type:
If the project uses…Load reference
Any .NET 10 project
references/csharp-compiler-dotnet9to10.md
Any .NET 10 project
references/core-libraries-dotnet9to10.md
Any .NET 10 project
references/sdk-msbuild-dotnet9to10.md
ASP.NET Core
references/aspnet-core-dotnet9to10.md
Entity Framework Core
references/efcore-dotnet9to10.md
Cryptography APIs
references/cryptography-dotnet9to10.md
Microsoft.Extensions.Hosting, BackgroundService, configuration
references/extensions-hosting-dotnet9to10.md
System.Text.Json, XmlSerializer, HttpClient, MailAddress, Uri
references/serialization-networking-dotnet9to10.md
Windows Forms or WPF
references/winforms-wpf-dotnet9to10.md
Docker containers, single-file apps, native interop
references/containers-interop-dotnet9to10.md
Common source-incompatible changes to check for:
  1. System.Linq.Async
    conflicts
    — Remove the
    System.Linq.Async
    package reference or upgrade to v7.0.0. If consumed transitively, add
    <ExcludeAssets>compile</ExcludeAssets>
    . Rename
    SelectAwait
    calls to
    Select
    where needed.
  2. New obsoletion warnings (SYSLIB0058–SYSLIB0062):
    • SYSLIB0058
      : Replace
      SslStream.KeyExchangeAlgorithm
      /
      CipherAlgorithm
      /
      HashAlgorithm
      with
      NegotiatedCipherSuite
      — if the old properties were used to reject weak TLS ciphers, preserve equivalent validation logic using the new API
    • SYSLIB0059
      : Replace
      SystemEvents.EventsThreadShutdown
      with
      AppDomain.ProcessExit
    • SYSLIB0060
      : Replace
      Rfc2898DeriveBytes
      constructors with
      Rfc2898DeriveBytes.Pbkdf2
    • SYSLIB0061
      : Replace
      Queryable.MaxBy
      /
      MinBy
      overloads taking
      IComparer<TSource>
      with ones taking
      IComparer<TKey>
    • SYSLIB0062
      : Replace
      XsltSettings.EnableScript
      usage
  3. C# 14
    field
    keyword in property accessors
    — The identifier
    field
    is now a contextual keyword inside property
    get
    /
    set
    /
    init
    accessors. Local variables named
    field
    cause CS9272 (error). Class members named
    field
    referenced without
    this.
    cause CS9258 (warning). Fix by renaming (e.g.,
    fieldValue
    ) or escaping with
    @field
    . See
    references/csharp-compiler-dotnet9to10.md
    .
  4. C# 14
    extension
    contextual keyword
    — Types, aliases, or type parameters named
    extension
    are disallowed. Rename or escape with
    @extension
    .
  5. C# 14 overload resolution with span parameters — Expression trees containing
    .Contains()
    on arrays may now bind to
    MemoryExtensions.Contains
    instead of
    Enumerable.Contains
    .
    Enumerable.Reverse
    on arrays may resolve to the in-place
    Span
    extension. Fix by casting to
    IEnumerable<T>
    , using
    .AsEnumerable()
    , or explicit static invocations. See
    references/csharp-compiler-dotnet9to10.md
    for full details.
  6. ASP.NET Core obsoletions (if applicable):
    • WebHostBuilder
      ,
      IWebHost
      ,
      WebHost
      are obsolete — migrate to
      Host.CreateDefaultBuilder
      or
      WebApplication.CreateBuilder
    • IActionContextAccessor
      /
      ActionContextAccessor
      obsolete
    • WithOpenApi
      extension method deprecated
    • IncludeOpenAPIAnalyzers
      property deprecated
    • IPNetwork
      and
      ForwardedHeadersOptions.KnownNetworks
      obsolete
    • Razor runtime compilation is obsolete
    • Microsoft.Extensions.ApiDescription.Client
      package deprecated
    • Microsoft.OpenApi
      v2.x breaking changes
      Microsoft.AspNetCore.OpenApi 10.0
      pulls in
      Microsoft.OpenApi
      v2.x which restructures namespaces and models.
      OpenApiString
      /
      OpenApiAny
      types are removed (use
      JsonNode
      ),
      OpenApiSecurityScheme.Reference
      replaced by
      OpenApiSecuritySchemeReference
      , collections on OpenAPI model objects may be null, and
      OpenApiSchema.Nullable
      is removed. See
      references/aspnet-core-dotnet9to10.md
      for migration patterns.
  7. SDK changes:
    • dotnet new sln
      now defaults to SLNX format — use
      --format sln
      if the old format is needed
    • Double quotes in file-level directives are disallowed
    • dnx.ps1
      removed from .NET SDK
    • project.json
      no longer supported in
      dotnet restore
  8. EF Core source changes (if applicable) — See
    references/efcore-dotnet9to10.md
    for:
    • ExecuteUpdateAsync
      now accepts a regular lambda (expression tree construction code must be rewritten)
    • IDiscriminatorPropertySetConvention
      signature changed
    • IRelationalCommandDiagnosticsLogger
      methods add
      logCommandText
      parameter
  9. WinForms/WPF source changes (if applicable):
    • Applications referencing both WPF and WinForms must disambiguate
      MenuItem
      and
      ContextMenu
      types
    • Renamed parameter in
      HtmlElement.InsertAdjacentElement
    • Empty
      ColumnDefinitions
      and
      RowDefinitions
      are disallowed in WPF
  10. Cryptography source changes (if applicable):
  • MLDsa
    and
    SlhDsa
    members renamed from
    SecretKey
    to
    PrivateKey
    (e.g.,
    ExportMLDsaSecretKey
    ExportMLDsaPrivateKey
    ,
    SecretKeySizeInBytes
    PrivateKeySizeInBytes
    )
  • Rfc2898DeriveBytes
    constructors are obsolete (SYSLIB0060) — replace with static
    Rfc2898DeriveBytes.Pbkdf2(password, salt, iterations, hashAlgorithm, outputLength)
  • CoseSigner.Key
    can now be null — check for null before use
  • X509Certificate.GetKeyAlgorithmParameters()
    and
    PublicKey.EncodedParameters
    can return null
  • Environment variable renamed from
    CLR_OPENSSL_VERSION_OVERRIDE
    to
    DOTNET_OPENSSL_VERSION_OVERRIDE
Build again after each batch of fixes. Repeat until the build is clean.
系统地处理编译错误和新警告。根据项目类型加载对应的参考文档:
项目使用的技术加载的参考文档
任何.NET 10项目
references/csharp-compiler-dotnet9to10.md
任何.NET 10项目
references/core-libraries-dotnet9to10.md
任何.NET 10项目
references/sdk-msbuild-dotnet9to10.md
ASP.NET Core
references/aspnet-core-dotnet9to10.md
Entity Framework Core
references/efcore-dotnet9to10.md
加密API
references/cryptography-dotnet9to10.md
Microsoft.Extensions.Hosting、BackgroundService、配置
references/extensions-hosting-dotnet9to10.md
System.Text.Json、XmlSerializer、HttpClient、MailAddress、Uri
references/serialization-networking-dotnet9to10.md
Windows Forms或WPF
references/winforms-wpf-dotnet9to10.md
Docker容器、单文件应用、本地互操作
references/containers-interop-dotnet9to10.md
需要检查的常见源代码不兼容变更:
  1. System.Linq.Async
    冲突
    — 移除
    System.Linq.Async
    包引用或升级至v7.0.0。若为传递依赖,添加
    <ExcludeAssets>compile</ExcludeAssets>
    。必要时将
    SelectAwait
    调用重命名为
    Select
  2. 新的弃用警告(SYSLIB0058–SYSLIB0062)
    • SYSLIB0058
      :用
      NegotiatedCipherSuite
      替换
      SslStream.KeyExchangeAlgorithm
      /
      CipherAlgorithm
      /
      HashAlgorithm
      ——如果旧属性用于拒绝弱TLS密码套件,请使用新API保留等效的验证逻辑
    • SYSLIB0059
      :用
      AppDomain.ProcessExit
      替换
      SystemEvents.EventsThreadShutdown
    • SYSLIB0060
      :用
      Rfc2898DeriveBytes.Pbkdf2
      替换
      Rfc2898DeriveBytes
      构造函数
    • SYSLIB0061
      :用接受
      IComparer<TKey>
      的重载替换
      Queryable.MaxBy
      /
      MinBy
      中接受
      IComparer<TSource>
      的重载
    • SYSLIB0062
      :替换
      XsltSettings.EnableScript
      的使用
  3. C# 14属性访问器中的
    field
    关键字
    — 在属性的
    get
    /
    set
    /
    init
    访问器内部,标识符
    field
    现在是上下文关键字。名为
    field
    的局部变量会引发CS9272错误。未使用
    this.
    引用的名为
    field
    的类成员会引发CS9258警告。修复方式为重命名(如
    fieldValue
    )或使用
    @field
    转义。详情见
    references/csharp-compiler-dotnet9to10.md
  4. C# 14
    extension
    上下文关键字
    — 不允许将类型、别名或类型参数命名为
    extension
    。重命名或使用
    @extension
    转义。
  5. C# 14中带span参数的重载解析 — 数组上调用
    .Contains()
    的表达式树现在可能绑定到
    MemoryExtensions.Contains
    而非
    Enumerable.Contains
    。数组上的
    Enumerable.Reverse
    可能解析为原地修改的
    Span
    扩展方法。修复方式为强制转换为
    IEnumerable<T>
    、使用
    .AsEnumerable()
    或显式静态调用。详情见
    references/csharp-compiler-dotnet9to10.md
  6. ASP.NET Core弃用项(若适用):
    • WebHostBuilder
      IWebHost
      WebHost
      已弃用——迁移至
      Host.CreateDefaultBuilder
      WebApplication.CreateBuilder
    • IActionContextAccessor
      /
      ActionContextAccessor
      已弃用
    • WithOpenApi
      扩展方法已弃用
    • IncludeOpenAPIAnalyzers
      属性已弃用
    • IPNetwork
      ForwardedHeadersOptions.KnownNetworks
      已弃用
    • Razor运行时编译已弃用
    • Microsoft.Extensions.ApiDescription.Client
      包已弃用
    • Microsoft.OpenApi
      v2.x重大变更
      Microsoft.AspNetCore.OpenApi 10.0
      引入了
      Microsoft.OpenApi
      v2.x,该版本重构了命名空间和模型。
      OpenApiString
      /
      OpenApiAny
      类型已移除(使用
      JsonNode
      替代),
      OpenApiSecurityScheme.Reference
      OpenApiSecuritySchemeReference
      替代,OpenAPI模型对象上的集合可能为null,
      OpenApiSchema.Nullable
      已移除。迁移模式详情见
      references/aspnet-core-dotnet9to10.md
  7. SDK变更
    • dotnet new sln
      现在默认生成SLNX格式——若需要旧格式请使用
      --format sln
    • 文件级指令中不允许使用双引号
    • .NET SDK中移除了
      dnx.ps1
    • dotnet restore
      不再支持
      project.json
  8. EF Core源代码变更(若适用)——详情见
    references/efcore-dotnet9to10.md
    • ExecuteUpdateAsync
      现在接受常规lambda表达式(需要重写表达式树构造代码)
    • IDiscriminatorPropertySetConvention
      签名变更
    • IRelationalCommandDiagnosticsLogger
      方法新增
      logCommandText
      参数
  9. WinForms/WPF源代码变更(若适用):
    • 同时引用WPF和WinForms的应用必须明确区分
      MenuItem
      ContextMenu
      类型
    • HtmlElement.InsertAdjacentElement
      的参数重命名
    • WPF中不允许空的
      ColumnDefinitions
      RowDefinitions
  10. 加密源代码变更(若适用):
    • MLDsa
      SlhDsa
      成员从
      SecretKey
      重命名为
      PrivateKey
      (如
      ExportMLDsaSecretKey
      ExportMLDsaPrivateKey
      SecretKeySizeInBytes
      PrivateKeySizeInBytes
    • Rfc2898DeriveBytes
      构造函数已弃用(SYSLIB0060)——替换为静态方法
      Rfc2898DeriveBytes.Pbkdf2(password, salt, iterations, hashAlgorithm, outputLength)
    • CoseSigner.Key
      现在可以为null——使用前需检查null
    • X509Certificate.GetKeyAlgorithmParameters()
      PublicKey.EncodedParameters
      可能返回null
    • 环境变量从
      CLR_OPENSSL_VERSION_OVERRIDE
      重命名为
      DOTNET_OPENSSL_VERSION_OVERRIDE
每修复一批问题后重新构建。重复此过程直到构建干净。

Step 4: Address behavioral changes

步骤4:处理行为变更

Behavioral changes do not cause build errors but may change runtime behavior. Review each applicable item and determine whether the previous behavior was relied upon.
High-impact behavioral changes (check first):
  1. SIGTERM signal handling removed — The .NET runtime no longer registers default SIGTERM handlers. If you rely on
    AppDomain.ProcessExit
    or
    AssemblyLoadContext.Unloading
    being raised on SIGTERM:
    • ASP.NET Core and Generic Host apps are unaffected (they register their own handlers)
    • Console apps and containerized apps without Generic Host must register
      PosixSignalRegistration.Create(PosixSignal.SIGTERM, _ => Environment.Exit(0))
      explicitly
  2. BackgroundService.ExecuteAsync runs entirely on a background thread — The synchronous portion before the first
    await
    no longer blocks startup. If startup ordering matters, move that code to
    StartAsync
    or the constructor, or implement
    IHostedLifecycleService
    .
  3. Configuration null values are now preserved — JSON
    null
    values are no longer converted to empty strings. Properties initialized with non-default values will be overwritten with
    null
    . Review configuration binding code.
  4. Microsoft.Data.Sqlite DateTimeOffset changes (all High impact):
    • GetDateTimeOffset
      without an offset now assumes UTC (previously assumed local)
    • Writing
      DateTimeOffset
      into REAL columns now converts to UTC first
    • GetDateTime
      with an offset now returns UTC with
      DateTimeKind.Utc
    • Mitigation:
      AppContext.SetSwitch("Microsoft.Data.Sqlite.Pre10TimeZoneHandling", true)
      as a temporary workaround
  5. EF Core parameterized collections
    .Contains()
    on collections now uses multiple scalar parameters instead of JSON/OPENJSON. May affect query performance for large collections. Mitigation:
    UseParameterizedCollectionMode(ParameterTranslationMode.Parameter)
    to revert.
  6. EF Core JSON data type on Azure SQL — Azure SQL and compatibility level ≥170 now use the
    json
    data type instead of
    nvarchar(max)
    . A migration will be generated to alter existing columns. Mitigation: set compatibility level to 160 or use
    HasColumnType("nvarchar(max)")
    explicitly.
  7. System.Text.Json property name conflict validation — Polymorphic types with properties conflicting with metadata names (
    $type
    ,
    $id
    ,
    $ref
    ) now throw
    InvalidOperationException
    . Add
    [JsonIgnore]
    to conflicting properties.
Other behavioral changes to review:
  • BufferedStream.WriteByte
    no longer implicitly flushes — add explicit
    Flush()
    calls if needed
  • Default trace context propagator updated to W3C standard
  • DriveInfo.DriveFormat
    returns actual Linux filesystem type names
  • LDAP
    DirectoryControl
    parsing is more stringent
  • Default .NET container images switched from Debian to Ubuntu (Debian images no longer shipped)
  • Single-file apps no longer look for native libraries in executable directory by default
  • DllImportSearchPath.AssemblyDirectory
    only searches the assembly directory
  • MailAddress
    enforces validation for consecutive dots
  • Streaming HTTP responses enabled by default in browser HTTP clients
  • Uri
    length limits removed — add explicit length validation if
    Uri
    was used to reject oversized input from untrusted sources
  • Cookie login redirects disabled for known API endpoints (ASP.NET Core)
  • XmlSerializer
    no longer ignores
    [Obsolete]
    properties — audit obsolete properties for sensitive data and add
    [XmlIgnore]
    to prevent unintended data exposure
  • dotnet restore
    audits transitive packages
  • dotnet watch
    logs to stderr instead of stdout
  • dotnet
    CLI commands log non-command-relevant data to stderr
  • Various NuGet behavioral changes (see
    references/sdk-msbuild-dotnet9to10.md
    )
  • StatusStrip
    uses System RenderMode by default (WinForms)
  • TreeView
    checkbox image truncation fix (WinForms)
  • DynamicResource
    incorrect usage causes crash (WPF)
行为变更不会导致构建错误,但可能改变运行时行为。审查每个适用项并确定是否依赖之前的行为。
高影响行为变更(优先检查):
  1. 移除SIGTERM信号处理 — .NET运行时不再注册默认SIGTERM处理程序。如果依赖
    AppDomain.ProcessExit
    AssemblyLoadContext.Unloading
    在SIGTERM时触发:
    • ASP.NET Core和通用宿主应用不受影响(它们会注册自己的处理程序)
    • 控制台应用和未使用通用宿主的容器化应用必须显式注册
      PosixSignalRegistration.Create(PosixSignal.SIGTERM, _ => Environment.Exit(0))
  2. BackgroundService.ExecuteAsync完全在后台线程运行 — 第一个
    await
    之前的同步部分不再阻塞启动。如果启动顺序很重要,请将该代码移至
    StartAsync
    或构造函数,或实现
    IHostedLifecycleService
  3. 配置空值现在被保留 — JSON
    null
    值不再转换为空字符串。使用非默认值初始化的属性会被
    null
    覆盖。审查配置绑定代码。
  4. Microsoft.Data.Sqlite DateTimeOffset变更(均为高影响):
    • 无偏移量的
      GetDateTimeOffset
      现在默认使用UTC(之前默认使用本地时间)
    • DateTimeOffset
      写入REAL列现在会先转换为UTC
    • 带偏移量的
      GetDateTime
      现在返回带
      DateTimeKind.Utc
      的UTC时间
    • 缓解措施:临时使用
      AppContext.SetSwitch("Microsoft.Data.Sqlite.Pre10TimeZoneHandling", true)
      作为变通方案
  5. EF Core参数化集合 — 集合上的
    .Contains()
    现在使用多个标量参数而非JSON/OPENJSON。对于大型集合可能影响查询性能。缓解措施:使用
    UseParameterizedCollectionMode(ParameterTranslationMode.Parameter)
    恢复旧行为。
  6. EF Core在Azure SQL上的JSON数据类型 — Azure SQL及兼容级别≥170现在使用
    json
    数据类型而非
    nvarchar(max)
    。会生成迁移来修改现有列。缓解措施:将兼容级别设置为160或显式使用
    HasColumnType("nvarchar(max)")
  7. System.Text.Json属性名称冲突验证 — 与元数据名称(
    $type
    $id
    $ref
    )冲突的多态类型属性现在会抛出
    InvalidOperationException
    。为冲突属性添加
    [JsonIgnore]
其他需要审查的行为变更:
  • BufferedStream.WriteByte
    不再隐式刷新——必要时添加显式
    Flush()
    调用
  • 默认跟踪上下文传播器更新为W3C标准
  • DriveInfo.DriveFormat
    返回实际的Linux文件系统类型名称
  • LDAP
    DirectoryControl
    解析更严格
  • 默认.NET容器镜像从Debian切换为Ubuntu(不再提供Debian镜像)
  • 单文件应用默认不再在可执行目录中查找本地库
  • DllImportSearchPath.AssemblyDirectory
    仅搜索程序集目录
  • MailAddress
    强制验证连续点
  • 浏览器HTTP客户端默认启用流式HTTP响应
  • Uri
    长度限制已移除——如果之前使用
    Uri
    拒绝来自不可信来源的超大输入,请添加显式长度验证
  • 已知API端点默认禁用Cookie登录重定向(ASP.NET Core)
  • XmlSerializer
    不再忽略
    [Obsolete]
    属性——审查包含敏感数据的弃用属性,添加
    [XmlIgnore]
    以防止意外数据泄露
  • dotnet restore
    审核传递依赖包
  • dotnet watch
    现在将日志输出到stderr而非stdout
  • dotnet
    CLI命令将与命令无关的数据输出到stderr
  • 各种NuGet行为变更(见
    references/sdk-msbuild-dotnet9to10.md
  • StatusStrip
    默认使用系统渲染模式(WinForms)
  • 修复
    TreeView
    复选框图像截断问题(WinForms)
  • 错误使用
    DynamicResource
    会导致崩溃(WPF)

Step 5: Update infrastructure

步骤5:更新基础设施

  1. Dockerfiles: Update base images. Default tags now use Ubuntu instead of Debian. Debian images are no longer shipped for .NET 10.
    dockerfile
    # Before
    FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
    FROM mcr.microsoft.com/dotnet/aspnet:9.0
    # After
    FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
    FROM mcr.microsoft.com/dotnet/aspnet:10.0
  2. CI/CD pipelines: Update SDK version references. If using
    global.json
    , update:
    json
    {
      "sdk": {
        "version": "10.0.100"
      }
    }
  3. Environment variables renamed:
    • DOTNET_OPENSSL_VERSION_OVERRIDE
      replaces the old name
    • DOTNET_ICU_VERSION_OVERRIDE
      replaces the old name
    • NUGET_ENABLE_ENHANCED_HTTP_RETRY
      has been removed
  4. OpenSSL requirements: OpenSSL 1.1.1 or later is now required on Unix. OpenSSL cryptographic primitives are no longer supported on macOS.
  5. Solution file format: If
    dotnet new sln
    is used in scripts, note it now generates SLNX format. Pass
    --format sln
    if the old format is needed.
  1. Dockerfile:更新基础镜像。默认标签现在使用Ubuntu而非Debian。.NET 10不再提供Debian镜像。
    dockerfile
    # 之前
    FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
    FROM mcr.microsoft.com/dotnet/aspnet:9.0
    # 之后
    FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
    FROM mcr.microsoft.com/dotnet/aspnet:10.0
  2. CI/CD流水线:更新SDK版本引用。若使用
    global.json
    ,更新为:
    json
    {
      "sdk": {
        "version": "10.0.100"
      }
    }
  3. 重命名的环境变量
    • DOTNET_OPENSSL_VERSION_OVERRIDE
      替代旧名称
    • DOTNET_ICU_VERSION_OVERRIDE
      替代旧名称
    • NUGET_ENABLE_ENHANCED_HTTP_RETRY
      已被移除
  4. OpenSSL要求:Unix系统现在需要OpenSSL 1.1.1或更高版本。macOS不再支持OpenSSL加密原语。
  5. 解决方案文件格式:如果脚本中使用
    dotnet new sln
    ,注意现在默认生成SLNX格式。若需要旧格式,请传递
    --format sln
    参数。

Step 6: Verify

步骤6:验证

  1. Run a full clean build:
    dotnet build --no-incremental
  2. Run all tests:
    dotnet test
  3. If the application is containerized, build and test the container image
  4. Smoke-test the application, paying special attention to:
    • Signal handling / graceful shutdown behavior
    • Background services startup ordering
    • Configuration binding with null values
    • Date/time handling with Sqlite
    • JSON serialization with polymorphic types
    • EF Core queries using
      .Contains()
      on collections
  5. Security review — verify that the migration has not weakened security controls:
    • TLS cipher validation logic is preserved after
      SslStream
      API migration (SYSLIB0058)
    • Obsolete properties containing sensitive data are excluded from serialization (
      [XmlIgnore]
      ,
      [JsonIgnore]
      )
    • Input validation still rejects oversized URIs if
      Uri
      was used as a length gate
    • Exception handlers emit security-relevant telemetry (auth failures, access violations) before returning
      true
    • Connection strings set an explicit
      Application Name
      that does not leak version info
    • dotnet restore
      vulnerability audit findings are addressed, not suppressed
  6. Review the diff and ensure no unintended behavioral changes were introduced
  1. 执行完整的干净构建:
    dotnet build --no-incremental
  2. 运行所有测试:
    dotnet test
  3. 如果应用是容器化的,构建并测试容器镜像
  4. 对应用进行冒烟测试,特别注意:
    • 信号处理/优雅关闭行为
    • 后台服务启动顺序
    • 带空值的配置绑定
    • Sqlite的日期/时间处理
    • 多态类型的JSON序列化
    • EF Core中使用
      .Contains()
      的集合查询
  5. 安全审查 — 验证迁移未削弱安全控制:
    • 迁移
      SslStream
      API(SYSLIB0058)后,TLS密码套件验证逻辑是否保留
    • 包含敏感数据的弃用属性是否已排除在序列化之外(
      [XmlIgnore]
      [JsonIgnore]
    • 如果之前使用
      Uri
      作为长度限制,是否添加了显式长度验证以拒绝超大输入
    • 异常处理程序在返回
      true
      前是否输出了安全相关遥测(认证失败、访问违规)
    • 连接字符串是否设置了明确的
      Application Name
      ,未泄露版本信息
    • dotnet restore
      的漏洞审计结果是否已处理,而非被压制
  6. 审查差异,确保未引入意外的行为变更

Reference Documents

参考文档

The
references/
folder contains detailed breaking change information organized by technology area. Load only the references relevant to the project being migrated:
Reference fileWhen to load
references/csharp-compiler-dotnet9to10.md
Always (C# 14 compiler breaking changes — field keyword, extension keyword, span overloads)
references/core-libraries-dotnet9to10.md
Always (applies to all .NET 10 projects)
references/sdk-msbuild-dotnet9to10.md
Always (SDK and build tooling changes)
references/aspnet-core-dotnet9to10.md
Project uses ASP.NET Core
references/efcore-dotnet9to10.md
Project uses Entity Framework Core or Microsoft.Data.Sqlite
references/cryptography-dotnet9to10.md
Project uses System.Security.Cryptography or X.509 certificates
references/extensions-hosting-dotnet9to10.md
Project uses Generic Host, BackgroundService, or Microsoft.Extensions.Configuration
references/serialization-networking-dotnet9to10.md
Project uses System.Text.Json, XmlSerializer, HttpClient, or networking APIs
references/winforms-wpf-dotnet9to10.md
Project uses Windows Forms or WPF
references/containers-interop-dotnet9to10.md
Project uses Docker containers, single-file publishing, or native interop (P/Invoke)
references/
文件夹包含按技术领域分类的详细重大变更信息。仅加载与当前迁移项目相关的参考文档:
参考文件加载场景
references/csharp-compiler-dotnet9to10.md
始终加载(C# 14编译器重大变更——field关键字、extension关键字、span重载)
references/core-libraries-dotnet9to10.md
始终加载(适用于所有.NET 10项目)
references/sdk-msbuild-dotnet9to10.md
始终加载(SDK和构建工具变更)
references/aspnet-core-dotnet9to10.md
项目使用ASP.NET Core
references/efcore-dotnet9to10.md
项目使用Entity Framework Core或Microsoft.Data.Sqlite
references/cryptography-dotnet9to10.md
项目使用System.Security.Cryptography或X.509证书
references/extensions-hosting-dotnet9to10.md
项目使用通用宿主、BackgroundService或Microsoft.Extensions.Configuration
references/serialization-networking-dotnet9to10.md
项目使用System.Text.Json、XmlSerializer、HttpClient或网络API
references/winforms-wpf-dotnet9to10.md
项目使用Windows Forms或WPF
references/containers-interop-dotnet9to10.md
项目使用Docker容器、单文件发布或本地互操作(P/Invoke)