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