我们在使用 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)),也可以配合数据库函数优化。