ASP.NET Core JSON 中文編碼問題與序列化參數設定
| | 1 | | ![]() |
轉進 ASP.NET Core 世界,依循過去寫 MVC 經驗,加上參考網路技術文章(當然,還有流著奶與蜜的 Stackoverflow) 大致還算都順利,但不時發現新的眉角。
今天遇到的問題是 Razor Page 傳回 JsonResult 時,中文字元被轉成 UCN (Unicode Character Name,例如:"\u9ED1\u6697\u57F7\u884C\u7DD2") 編碼。Razor Page 程式範例如下,OnGetJsonData() 時使用 new JsonResult() 回傳簡單資料物件:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PTSWeb.Models.Data;
namespace PTSWeb.Pages
{
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger,)
{
_logger = logger;
}
public void OnGet()
{
}
public ActionResult OnGetJsonData()
{
return new JsonResult(new
{
Blog = "darkthread",
Name = "黑暗執行緒"
});
}
}
}
如下圖所示,在預設情況下,中文字串將會被轉換成 UCN,另外屬性名稱的第一個字元被轉成小寫(我慣用大寫,程式碼產生器處理時可保持前後端一致):
這類問題對對我不算陌生,之前在 cshtml 就遇過:ASP.NET Core View 中文變 & # x4E2D; & # x6587;,大約知道與 Encoder 設定有關,差別在上回是 HtmlEncoder,ASP.NET Core 3.0 起預設改用 System.Text.Json 處理 JSON 序列化與反序列化,找到方法調整 System.Text.Json 的 Encoder 設定即可解決。
查到做法是在 Startup.ConfigureServices() 的 AddRazorPages()、AddControllers()、AddMvc() 後接上 AddJsonOptions() 修改預設設定:(我一併取消屬性名稱強制轉頭文字小寫(Camel Case)的功能)
public void ConfigureServices(IServiceCollection services)
{
//... 略 ....
services.AddRazorPages()
.AddJsonOptions(options =>
{
//原本是 JsonNamingPolicy.CamelCase,強制頭文字轉小寫,我偏好維持原樣,設為null
options.JsonSerializerOptions.PropertyNamingPolicy = null;
//允許基本拉丁英文及中日韓文字維持原字元
options.JsonSerializerOptions.Encoder =
JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs);
});
}
搞定!
不過,很有預感未來很有可能因為 System.Text.Json 的某個限制讓我想換回 Json.NET,所以提前部署,預圥查了切回去使用 Json.NET 的方法:
先用 NuGet 安裝 Microsoft.AspNetCore.Mvc.NewtonsoftJson:
AddRazorPages()、AddControllers()、AddMvc() 後方接 AddNewtonsoftJson():(Json.NET 在 ASP.NET Core 預設也會將屬性名稱轉成頭文字小寫,要保持原樣需呼叫 UseMemberCasing() )
services.AddRazorPages()
.AddNewtonsoftJson(options =>
{
options.UseMemberCasing();
});
Hint of how to change default JSON serialization and deserialization settings in ASP.NET Core.
Comments
# by Ike
「屬性名稱的第一個字元被轉成小寫」這很討厭,怎麼可以擅自改掉呢