共用方式為


原生 AOT 的 ASP.NET Core 支援

作者 Mitch Denny

ASP.NET Core 8.0 推出 .NET 原生預先 (AOT) 的支援。

如需 Blazor WebAssembly 原生 AOT 指導,可在這篇文章中新增或取代指導,請參閱 ASP.NET Core Blazor WebAssembly 的組建工具和事先 (AOT) 編譯

為何搭配 ASP.NET Core 使用原生 AOT

發佈和部署原生 AOT 應用程式可提供下列優勢:

  • 最小化的磁碟使用量:使用原生 AOT 發佈時,會產生單一可執行檔,其中只包含來自外部相依性的程式碼,其是支援程式所需的程式碼。 減少的可執行檔案大小可能會導致:
    • 較小的容器映像,例如在容器化部署案例中。
    • 從較小的映像進行部署的時間減少。
  • 減少的啟動時間:原生 AOT 應用程式可以顯示減少的啟動時間,這表示
    • 應用程式已準備好更快地服務要求。
    • 改善的部署,其中容器協調器需要管理從應用程式某個版本到另一個版本的轉換。
  • 減少的記憶體需求:原生 AOT 應用程式可以減少記憶體需求,取決於應用程式所做的工作。 減少的記憶體使用量可能會導致更大的部署密度和改善的可擴縮性。

範本應用程式是在基準實驗室中執行,以比較下列應用程式的效能:AOT 發佈的應用程式、修剪的執行階段應用程式,以及未修剪的執行階段應用程式。 下圖顯示基準的結果:

此圖表顯示 AOT 發佈的應用程式、已修剪的執行階段應用程式,以及未修剪的執行階段應用程式的應用程式大小、記憶體使用量和啟動時間計量的比較。

上圖顯示原生 AOT 具有較低的應用程式大小、記憶體使用量和啟動時間。

ASP.NET Core 與原生 AOT 相容性

目前,並非 ASP.NET Core 中的所有功能都與原生 AOT 相容。 下表概括 ASP.NET Core 功能與原生 AOT 的相容性:

功能 完全支援 部分支援 不支援
gRPC 完全支援
最小 API 部分支援
MVC 不支援
Blazor Server 不支援
SignalR 部分支援
JWT 驗證 完全支援
其他驗證 不支援
CORS 完全支援
HealthChecks 完全支援
HttpLogging 完全支援
當地語系化 完全支援
OutputCaching 完全支援
RateLimiting 完全支援
RequestDecompression 完全支援
ResponseCaching 完全支援
ResponseCompression 完全支援
Rewrite 完全支援
工作階段 不支援
Spa 不支援
StaticFiles 完全支援
WebSocket 完全支援

有關限制的詳細資訊,請參閱:

移至原生 AOT 部署模型時,請務必徹底測試應用程式。 應該測試 AOT 部署的應用程式,以驗證功能是否尚未從未修剪的應用程式和 JIT 編譯的應用程式變更。 建置應用程式時,請檢閱並更正 AOT 警告。 在發佈期間發出 AOT 警告的應用程式可能無法正常運作。 如果在發佈時未發出 AOT 警告,則發佈的 AOT 應用程式應與未修剪且 JIT 編譯的應用程式運作相同。

原生 AOT 發佈

原生 AOT 是使用 PublishAot MSBuild 屬性啟用的。 下列範例展示如何在專案檔中啟用原生 AOT:

<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>

此設定會在發佈期間啟用原生 AOT 編譯,並在建置和編輯期間啟用動態程式碼使用量分析。 在本機執行時,使用原生 AOT 發佈的專案會使用 JIT 編譯。 AOT 應用程式與 JIT 編譯的應用程式有下列差異:

  • 與原生 AOT 不相容的功能會停用,並在執行階段擲回例外狀況。
  • 系統會啟用來源分析器,以醒目提示與原生 AOT 不相容的程式碼。 在發佈時,會再次分析整個應用程式 (包括 NuGet 套件) 是否相容。

原生 AOT 分析包含應用程式的所有程式碼,以及應用程式依賴的程式庫。 檢閱原生 AOT 警告並採取更正步驟。 最好經常發佈應用程式,以在開發生命週期早期發現問題。

在 .NET 8 中,下列 ASP.NET Core 應用程式類型支援原生 AOT:

Web API (原生 AOT) 範本

ASP.NET Core Web API (原生 AOT) 範本 (簡稱為 webapiaot) 會建立已啟用 AOT 的專案。 此範本在下列方式中與 Web API 專案範本不同:

  • 僅使用基本 API,因為 MVC 尚未與原生 AOT 相容。
  • 使用 CreateSlimBuilder() API 來確保預設只會啟用基本功能,從而將應用程式的部署大小降至最低。
  • 設定為只接聽 HTTP,因為 HTTPS 流量通常是由雲端原生部署中的輸入服務處理。
  • 不包含在 IIS 或 IIS Express 下執行的啟動設定檔。
  • 建立一個使用範例 HTTP 要求所設定的 .http 檔案,這些要求可以傳送至應用程式的端點。
  • 包含範例 Todo API,而不是天氣預報範例。
  • PublishAot 新增至專案檔,如本文稍早所示。
  • 啟用 JSON 序列化程式來源產生器。 來源產生器是用來在建置階段產生序列化程式碼,這是原生 AOT 編譯所需的字碼。

支援來源產生的變更

下列範例會顯示新增至 Program.cs 檔案的程式碼,即可支援 JSON 序列化來源產生:

using MyFirstAotWebApi;
+using System.Text.Json.Serialization;

-var builder = WebApplication.CreateBuilder();
+var builder = WebApplication.CreateSlimBuilder(args);

+builder.Services.ConfigureHttpJsonOptions(options =>
+{
+  options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
+});

var app = builder.Build();

var sampleTodos = TodoGenerator.GenerateTodos().ToArray();

var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
    sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
        ? Results.Ok(todo)
        : Results.NotFound());

app.Run();

+[JsonSerializable(typeof(Todo[]))]
+internal partial class AppJsonSerializerContext : JsonSerializerContext
+{
+
+}

若少了這組新增的程式碼,System.Text.Json 就會使用反映來將 JSON 序列化並還原序列化。 原生 AOT 中不支援反映。

如需詳細資訊,請參閱

launchSettings.json 的變更

Web API (原生 AOT) 範本所建立的 launchSettings.json 檔案已移除 iisSettings 區段和 IIS Express 設定檔:

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
-  "iisSettings": {
-     "windowsAuthentication": false,
-     "anonymousAuthentication": true,
-     "iisExpress": {
-       "applicationUrl": "http://localhost:11152",
-       "sslPort": 0
-     }
-   },
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "todos",
      "applicationUrl": "http://localhost:5102",
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
        }
      },
-     "IIS Express": {
-       "commandName": "IISExpress",
-       "launchBrowser": true,
-       "launchUrl": "todos",
-      "environmentVariables": {
-       "ASPNETCORE_ENVIRONMENT": "Development"
-      }
-    }
  }
}

CreateSlimBuilder 方法

此範本會使用 CreateSlimBuilder() 方法,而不是 CreateBuilder() 方法。

using System.Text.Json.Serialization;
using MyFirstAotWebApi;

var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.AddConsole();

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});

var app = builder.Build();

var sampleTodos = TodoGenerator.GenerateTodos().ToArray();

var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
    sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
        ? Results.Ok(todo)
        : Results.NotFound());

app.Run();

[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

CreateSlimBuilder 方法會使用執行應用程式所需的最少 ASP.NET Core 功能來初始化 WebApplicationBuilder

如先前所述,CreateSlimBuilder 方法不包含 HTTPS 或 HTTP/3 的支援。 在 TLS 終止 Proxy 後面執行的應用程式通常不需要這些通訊協定。 如需範例,請參閱 TLS 終止和端對端 TLS 搭配應用程式閘道。 HTTPS 可藉由呼叫 builder.WebHost.UseKestrelHttpsConfiguration 可透過呼叫啟用 HTTP/3 builder.WebHost.UseQuic

CreateSlimBuilderCreateBuilder

CreateSlimBuilder 方法不支援 CreateBuilder 方法所支援的下列功能:

CreateSlimBuilder 方法包含有效開發體驗所需的下列功能:

  • 適用於 appsettings.jsonappsettings.{EnvironmentName}.json 的 JSON 檔案設定
  • 使用者祕密組態。
  • 主控台記錄。
  • 記錄設定。

有關省略上述功能的建立器,請參閱 CreateEmptyBuilder 方法

包含最少功能對於修剪以及 AOT 都有好處。 如需詳細資訊,請參閱修剪獨立式部署及可執行檔

如需詳細資訊,請參閱比較 WebApplication.CreateBuilderCreateSlimBuilder

來源產生器

因為未使用的程式碼會在針對原生 AOT 發佈期間進行修剪,所以應用程式無法在執行階段使用未繫結的反映。 來源產生器是用來產生避免需要反映的程式碼。 在某些情況下,即使不需要產生器,來源產生器仍會產生針對 AOT 最佳化的程式碼。

若要檢視產生的原始程式碼,請將 EmitCompilerGeneratedFiles 屬性新增至應用程式的 .csproj 檔案,如下列範例所示:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <!-- Other properties omitted for brevity -->
    <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
  </PropertyGroup>

</Project>

執行 dotnet build 命令以查看產生的程式碼。 輸出包括 obj/Debug/net8.0/generated/ 目錄,其中包含針對專案產生的所有檔案。

dotnet publish 命令也會編譯來源檔案,並產生已編譯的檔案。 此外,dotnet publish 也會將產生的組件傳遞至原生 IL 編譯器。 IL 編譯器會產生原生可執行檔。 原生可執行檔包含原生機器碼。

程式庫和原生 AOT

ASP.NET Core 專案中所使用的許多熱門程式庫,在以原生 AOT 為目標的專案中使用時,目前會有一些相容性問題,例如:

  • 使用反映來檢查及探索類型。
  • 有條件地在執行階段載入程式庫。
  • 即時產生程式碼以實作功能。

您必須更新使用這些動態功能的程式庫,才能使用原生 AOT。 您可以使用 Roslyn 來源產生器之類的工具來加以更新。

建議想要支援原生 AOT 的程式庫作者:

基本 API 和 JSON 承載

基本 API 架構會進行最佳化,以供使用 System.Text.Json 接收和傳回 JSON 承載。 System.Text.Json

在基本 API 應用程式中作為 HTTP 內容一部分傳輸或從要求委派中傳回的所有類型,都必須在透過 ASP.NET Core 相依性插入註冊的 JsonSerializerContext 上進行設定:

using System.Text.Json.Serialization;
using MyFirstAotWebApi;

var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.AddConsole();

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});

var app = builder.Build();

var sampleTodos = TodoGenerator.GenerateTodos().ToArray();

var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
    sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
        ? Results.Ok(todo)
        : Results.NotFound());

app.Run();

[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

在上述醒目提示的程式碼中:

委派上「未」繫結至主體且不需要可序列化的參數。 例如,屬於豐富物件類型並實作 IParsable<T> 的查詢字串參數。

public class Todo
{
    public int Id { get; set; }
    public string? Title { get; set; }
    public DateOnly? DueBy { get; set; }
    public bool IsComplete { get; set; }
}

static class TodoGenerator
{
    private static readonly (string[] Prefixes, string[] Suffixes)[] _parts = new[]
        {
            (new[] { "Walk the", "Feed the" }, new[] { "dog", "cat", "goat" }),
            (new[] { "Do the", "Put away the" }, new[] { "groceries", "dishes", "laundry" }),
            (new[] { "Clean the" }, new[] { "bathroom", "pool", "blinds", "car" })
        };
    // Remaining code omitted for brevity.

已知問題

請參閱此 GitHub 問題,以報告或檢閱 ASP.NET Core 中原生 AOT 支援的問題。

另請參閱

ASP.NET Core 8.0 推出 .NET 原生預先 (AOT) 的支援。

為何搭配 ASP.NET Core 使用原生 AOT

發佈和部署原生 AOT 應用程式可提供下列優勢:

  • 最小化的磁碟使用量:使用原生 AOT 發佈時,會產生單一可執行檔,其中只包含來自外部相依性的程式碼,其是支援程式所需的程式碼。 減少的可執行檔案大小可能會導致:
    • 較小的容器映像,例如在容器化部署案例中。
    • 從較小的映像進行部署的時間減少。
  • 減少的啟動時間:原生 AOT 應用程式可以顯示減少的啟動時間,這表示
    • 應用程式已準備好更快地服務要求。
    • 改善的部署,其中容器協調器需要管理從應用程式某個版本到另一個版本的轉換。
  • 減少的記憶體需求:原生 AOT 應用程式可以減少記憶體需求,取決於應用程式所做的工作。 減少的記憶體使用量可能會導致更大的部署密度和改善的可擴縮性。

範本應用程式是在基準實驗室中執行,以比較下列應用程式的效能:AOT 發佈的應用程式、修剪的執行階段應用程式,以及未修剪的執行階段應用程式。 下圖顯示基準的結果:

此圖表顯示 AOT 發佈的應用程式、已修剪的執行階段應用程式,以及未修剪的執行階段應用程式的應用程式大小、記憶體使用量和啟動時間計量的比較。

上圖顯示原生 AOT 具有較低的應用程式大小、記憶體使用量和啟動時間。

ASP.NET Core 與原生 AOT 相容性

目前,並非 ASP.NET Core 中的所有功能都與原生 AOT 相容。 下表概括 ASP.NET Core 功能與原生 AOT 的相容性:

功能 完全支援 部分支援 不支援
gRPC 完全支援
最小 API 部分支援
MVC 不支援
Blazor Server 不支援
SignalR 不支援
JWT 驗證 完全支援
其他驗證 不支援
CORS 完全支援
HealthChecks 完全支援
HttpLogging 完全支援
當地語系化 完全支援
OutputCaching 完全支援
RateLimiting 完全支援
RequestDecompression 完全支援
ResponseCaching 完全支援
ResponseCompression 完全支援
Rewrite 完全支援
工作階段 不支援
Spa 不支援
StaticFiles 完全支援
WebSocket 完全支援

有關限制的詳細資訊,請參閱:

移至原生 AOT 部署模型時,請務必徹底測試應用程式。 應該測試 AOT 部署的應用程式,以驗證功能是否尚未從未修剪的應用程式和 JIT 編譯的應用程式變更。 建置應用程式時,請檢閱並更正 AOT 警告。 在發佈期間發出 AOT 警告的應用程式可能無法正常運作。 如果在發佈時未發出 AOT 警告,則發佈的 AOT 應用程式應與未修剪且 JIT 編譯的應用程式運作相同。

原生 AOT 發佈

原生 AOT 是使用 PublishAot MSBuild 屬性啟用的。 下列範例展示如何在專案檔中啟用原生 AOT:

<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>

此設定會在發佈期間啟用原生 AOT 編譯,並在建置和編輯期間啟用動態程式碼使用量分析。 在本機執行時,使用原生 AOT 發佈的專案會使用 JIT 編譯。 AOT 應用程式與 JIT 編譯的應用程式有下列差異:

  • 與原生 AOT 不相容的功能會停用,並在執行階段擲回例外狀況。
  • 系統會啟用來源分析器,以醒目提示與原生 AOT 不相容的程式碼。 在發佈時,會再次分析整個應用程式 (包括 NuGet 套件) 是否相容。

原生 AOT 分析包含應用程式的所有程式碼,以及應用程式依賴的程式庫。 檢閱原生 AOT 警告並採取更正步驟。 最好經常發佈應用程式,以在開發生命週期早期發現問題。

在 .NET 8 中,下列 ASP.NET Core 應用程式類型支援原生 AOT:

Web API (原生 AOT) 範本

ASP.NET Core Web API (原生 AOT) 範本 (簡稱為 webapiaot) 會建立已啟用 AOT 的專案。 此範本在下列方式中與 Web API 專案範本不同:

  • 僅使用基本 API,因為 MVC 尚未與原生 AOT 相容。
  • 使用 CreateSlimBuilder() API 來確保預設只會啟用基本功能,從而將應用程式的部署大小降至最低。
  • 設定為只接聽 HTTP,因為 HTTPS 流量通常是由雲端原生部署中的輸入服務處理。
  • 不包含在 IIS 或 IIS Express 下執行的啟動設定檔。
  • 建立一個使用範例 HTTP 要求所設定的 .http 檔案,這些要求可以傳送至應用程式的端點。
  • 包含範例 Todo API,而不是天氣預報範例。
  • PublishAot 新增至專案檔,如本文稍早所示。
  • 啟用 JSON 序列化程式來源產生器。 來源產生器是用來在建置階段產生序列化程式碼,這是原生 AOT 編譯所需的字碼。

支援來源產生的變更

下列範例會顯示新增至 Program.cs 檔案的程式碼,即可支援 JSON 序列化來源產生:

using MyFirstAotWebApi;
+using System.Text.Json.Serialization;

-var builder = WebApplication.CreateBuilder();
+var builder = WebApplication.CreateSlimBuilder(args);

+builder.Services.ConfigureHttpJsonOptions(options =>
+{
+  options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
+});

var app = builder.Build();

var sampleTodos = TodoGenerator.GenerateTodos().ToArray();

var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
    sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
        ? Results.Ok(todo)
        : Results.NotFound());

app.Run();

+[JsonSerializable(typeof(Todo[]))]
+internal partial class AppJsonSerializerContext : JsonSerializerContext
+{
+
+}

若少了這組新增的程式碼,System.Text.Json 就會使用反映來將 JSON 序列化並還原序列化。 原生 AOT 中不支援反映。

如需詳細資訊,請參閱

launchSettings.json 的變更

Web API (原生 AOT) 範本所建立的 launchSettings.json 檔案已移除 iisSettings 區段和 IIS Express 設定檔:

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
-  "iisSettings": {
-     "windowsAuthentication": false,
-     "anonymousAuthentication": true,
-     "iisExpress": {
-       "applicationUrl": "http://localhost:11152",
-       "sslPort": 0
-     }
-   },
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "todos",
      "applicationUrl": "http://localhost:5102",
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
        }
      },
-     "IIS Express": {
-       "commandName": "IISExpress",
-       "launchBrowser": true,
-       "launchUrl": "todos",
-      "environmentVariables": {
-       "ASPNETCORE_ENVIRONMENT": "Development"
-      }
-    }
  }
}

CreateSlimBuilder 方法

此範本會使用 CreateSlimBuilder() 方法,而不是 CreateBuilder() 方法。

using System.Text.Json.Serialization;
using MyFirstAotWebApi;

var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.AddConsole();

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});

var app = builder.Build();

var sampleTodos = TodoGenerator.GenerateTodos().ToArray();

var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
    sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
        ? Results.Ok(todo)
        : Results.NotFound());

app.Run();

[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

CreateSlimBuilder 方法會使用執行應用程式所需的最少 ASP.NET Core 功能來初始化 WebApplicationBuilder

如先前所述,CreateSlimBuilder 方法不包含 HTTPS 或 HTTP/3 的支援。 在 TLS 終止 Proxy 後面執行的應用程式通常不需要這些通訊協定。 如需範例,請參閱 TLS 終止和端對端 TLS 搭配應用程式閘道。 HTTPS 可藉由呼叫 builder.WebHost.UseKestrelHttpsConfiguration 可透過呼叫啟用 HTTP/3 builder.WebHost.UseQuic

CreateSlimBuilderCreateBuilder

CreateSlimBuilder 方法不支援 CreateBuilder 方法所支援的下列功能:

CreateSlimBuilder 方法包含有效開發體驗所需的下列功能:

  • 適用於 appsettings.jsonappsettings.{EnvironmentName}.json 的 JSON 檔案設定
  • 使用者祕密組態。
  • 主控台記錄。
  • 記錄設定。

有關省略上述功能的建立器,請參閱 CreateEmptyBuilder 方法

包含最少功能對於修剪以及 AOT 都有好處。 如需詳細資訊,請參閱修剪獨立式部署及可執行檔

如需詳細資訊,請參閱比較 WebApplication.CreateBuilderCreateSlimBuilder

來源產生器

因為未使用的程式碼會在針對原生 AOT 發佈期間進行修剪,所以應用程式無法在執行階段使用未繫結的反映。 來源產生器是用來產生避免需要反映的程式碼。 在某些情況下,即使不需要產生器,來源產生器仍會產生針對 AOT 最佳化的程式碼。

若要檢視產生的原始程式碼,請將 EmitCompilerGeneratedFiles 屬性新增至應用程式的 .csproj 檔案,如下列範例所示:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <!-- Other properties omitted for brevity -->
    <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
  </PropertyGroup>

</Project>

執行 dotnet build 命令以查看產生的程式碼。 輸出包括 obj/Debug/net8.0/generated/ 目錄,其中包含針對專案產生的所有檔案。

dotnet publish 命令也會編譯來源檔案,並產生已編譯的檔案。 此外,dotnet publish 也會將產生的組件傳遞至原生 IL 編譯器。 IL 編譯器會產生原生可執行檔。 原生可執行檔包含原生機器碼。

程式庫和原生 AOT

ASP.NET Core 專案中所使用的許多熱門程式庫,在以原生 AOT 為目標的專案中使用時,目前會有一些相容性問題,例如:

  • 使用反映來檢查及探索類型。
  • 有條件地在執行階段載入程式庫。
  • 即時產生程式碼以實作功能。

您必須更新使用這些動態功能的程式庫,才能使用原生 AOT。 您可以使用 Roslyn 來源產生器之類的工具來加以更新。

建議想要支援原生 AOT 的程式庫作者:

基本 API 和 JSON 承載

基本 API 架構會進行最佳化,以供使用 System.Text.Json 接收和傳回 JSON 承載。 System.Text.Json

在基本 API 應用程式中作為 HTTP 內容一部分傳輸或從要求委派中傳回的所有類型,都必須在透過 ASP.NET Core 相依性插入註冊的 JsonSerializerContext 上進行設定:

using System.Text.Json.Serialization;
using MyFirstAotWebApi;

var builder = WebApplication.CreateSlimBuilder(args);
builder.Logging.AddConsole();

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});

var app = builder.Build();

var sampleTodos = TodoGenerator.GenerateTodos().ToArray();

var todosApi = app.MapGroup("/todos");
todosApi.MapGet("/", () => sampleTodos);
todosApi.MapGet("/{id}", (int id) =>
    sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
        ? Results.Ok(todo)
        : Results.NotFound());

app.Run();

[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

在上述醒目提示的程式碼中:

委派上「未」繫結至主體且不需要可序列化的參數。 例如,屬於豐富物件類型並實作 IParsable<T> 的查詢字串參數。

public class Todo
{
    public int Id { get; set; }
    public string? Title { get; set; }
    public DateOnly? DueBy { get; set; }
    public bool IsComplete { get; set; }
}

static class TodoGenerator
{
    private static readonly (string[] Prefixes, string[] Suffixes)[] _parts = new[]
        {
            (new[] { "Walk the", "Feed the" }, new[] { "dog", "cat", "goat" }),
            (new[] { "Do the", "Put away the" }, new[] { "groceries", "dishes", "laundry" }),
            (new[] { "Clean the" }, new[] { "bathroom", "pool", "blinds", "car" })
        };
    // Remaining code omitted for brevity.

已知問題

請參閱此 GitHub 問題,以報告或檢閱 ASP.NET Core 中原生 AOT 支援的問題。

另請參閱