我們在使用 Entity Framework Core(EF Core)
時,如果希望 全局設置 JSON 序列化和反序列化使用 UTF-8 編碼,通常需要配置 System.Text.Json
的默認行為,因為 EF Core 6.0
及以上版本默認使用 System.Text.Json
進行 JSON
操作。
? 場景說明
EF Core
中涉及 JSON
序列化的常見場景包括:
- 使用
HasConversion()
將復雜類型(如Dictionary
,List<T>
等)映射到數據庫字段; - 使用
FromSqlRaw()
或ExecuteSqlRaw()
執行返回JSON
的SQL
查詢; - 使用
ValueConverter
對自定義對象進行JSON
轉換; - 在
ASP.NET Core
中與System.Text.Json
配合使用處理API
請求/響應。
🧰 如何全局設置 UTF-8?
方法一:配置 EF Core 的 ValueConverter 使用 UTF-8
如果你是通過 HasConversion()
來轉換實體屬性為 JSON
字符串,可以顯式指定使用 UTF-8
:
modelBuilder.Entity<MyEntity>().Property(e => e.MyJsonField).HasConversion(v => JsonSerializer.Serialize(v, new JsonSerializerOptions { WriteIndented = false, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }),v => JsonSerializer.Deserialize<MyType>(v, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!);
💡 注意:
JavaScriptEncoder.UnsafeRelaxedJsonEscaping
可選,用于支持非ASCII
字符的直接輸出。
方法二:全局注冊 UTF-8 作為默認編碼(適用于 ASP.NET Core)
如果你使用的是 ASP.NET Core
,并且希望整個應用中所有 JSON
操作都使用 UTF-8
,可以在 Program.cs
或 Startup.cs
中配置:
.NET 6/7/8/9 示例(Program.cs):
var builder = WebApplication.CreateBuilder(args);// 全局配置 System.Text.Json 使用 UTF-8
builder.Services.Configure<JsonOptions>(options =>
{options.JsonSerializerOptions.WriteIndented = false;options.JsonSerializerOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping; // 支持中文等字符options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});
這樣 EF Core
在調用 ToJson()
、FromBody
、ToString()
等方法時也會使用此配置。
方法三:自定義 JsonValueConverterSelector(高級用法)
你可以創建一個繼承自 JsonValueConverterSelector
的類,并重寫其行為以全局控制 JSON
序列化選項。
public class Utf8JsonValueConverterSelector : JsonValueConverterSelector
{private readonly JsonSerializerOptions _options = new(){WriteIndented = false,Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping};public override ValueConverter? Select(Type modelClrType, Type providerClrType, DbContext context){if (providerClrType == typeof(string)){return new GenericJsonConverter(modelClrType, _options);}return base.Select(modelClrType, providerClrType, context);}
}
然后在 OnConfiguring
中注冊它:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{optionsBuilder.ReplaceService<IValueConverterSelector, Utf8JsonValueConverterSelector>();
}
📌 總結
方法 | 適用范圍 | 是否推薦 |
---|---|---|
顯式配置 HasConversion() | 單個字段 | ? 推薦 |
配置 JsonOptions 全局 | ASP.NET Core + EF Core API 層 | ? 推薦 |
自定義 JsonValueConverterSelector | 全局自動處理 JSON 字段 | 🔧 高級用法 |
🧪 示例:完整實體配置
public class MyEntity
{public int Id { get; set; }public Dictionary<string, object> Data { get; set; } = null!;
}// 配置:
modelBuilder.Entity<MyEntity>().Property(e => e.Data).HasConversion(v => JsonSerializer.Serialize(v, new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }),v => JsonSerializer.Deserialize<Dictionary<string, object>>(v)!);
這樣可以確保存儲和讀取 JSON
數據時始終使用 UTF-8
編碼,避免亂碼或無法解析的問題。
如需進一步結合數據庫字段類型(如 PostgreSQL
的 json/jsonb
、SQL Server
的 nvarchar(max)
),也可以配合數據庫函數優化。