需求:system.text.json.JsonSerializer.Serialize(returnData) ,由于 returnData 对象种的的其中一个属性是中文的。当我调用上面这个方法时,序列化出来的还是转码之后的字符集。
我在 startup 设置了全局序列化配置项
services.AddControllers().AddJsonOptions(config =>
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
});
结果控制器端调用 JsonSerializer.Serialize(returnData) 还是中文转码字符集
刚开始以为 UnsafeRelaxedJsonEscaping
没效果,就按 https://q.cnblogs.com/q/115234/ 上的问题全部来一遍,发现还是不行。
之后我做了以下措施:
在控制器注入 JsonOption 发现我之前加的全局设置都存在。但是不知在使用这个方法时没效果。
后来我在源码上看到这么一行代码
JsonSerializer.Serialize 在没有传 setting 的时候是调用了 JsonSerializerOptions.s_defaultOptions 这个单例对象,但是往后查我就不知道是在哪里进行赋值的了,而且在我另一个项目这么写是没问题的。
所以想请问下,这种情况是什么原因导致的?
备注:直接调用 JsonSerializer.Serialize(returnData, option)
这样是没有问题的
我所有的分都上了
.net core 3.1 还不支持全局设置 JsonSerializer 的 JsonSerializerOptions ,需要在 Serialize 方法中传入。
var json = JsonSerializer.Serialize(
new { Title = "代码改变世界" },
new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) });
详见 How to globally set default options for System.Text.Json.JsonSerializer?
也可以通过注入 IOptions<JsonOptions>
使用 Statup 中配置的 JsonOptions
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly JsonOptions _jsonOptions;
public HomeController(ILogger<HomeController> logger, IOptions<JsonOptions> jsonOptions)
{
_logger = logger;
_jsonOptions = jsonOptions.Value;
}
public IActionResult Index()
{
var json = JsonSerializer.Serialize(
new { Title = "代码改变世界" },
_jsonOptions.JsonSerializerOptions);
return Content(json);
}
}
@dudu: 谢谢,我还以为支持。不过由于知道了源代码里面的结构,也知道 JsonSerializerOptions.s_defaultOptions
是一个单例,所以可以采用另一种方式来达到全局序列化器的作用,代码如下:
再 startup.Configure 方法种写入
var fieldInfo = typeof(JsonSerializerOptions).GetField("s_defaultOptions", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance);
var options = fieldInfo.GetValue(null) as JsonSerializerOptions;
options.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
这样就不用在每个序列化方法去传入 option 了
@沉睡的木木夕: 赞!巧妙使用反射解决了问题。
原来是不支持,困扰了我一天了,网上哪些全部雷同的全局设置估计都是ctrl+c,ctrl+v的,感谢解惑!
我只是为了收藏解决方案的 (/ω\)