dotnet核心System.Text.Json Unscape Unicode字符串

时间:2019-09-19 03:23:23

标签: c# .net json .net-core system.text.json

使用JsonSerializer.Serialize(obj);将产生一个转义的字符串,但是我想要未转义的版本。例如:

using System;
using System.Text.Json;

public class Program
{
    public static void Main()
    {
            var a = new A{Name = "你好"};
            var s = JsonSerializer.Serialize(a);
            Console.WriteLine(s);
        }
}

class A {
    public string Name {get; set;}
}

将产生一个字符串{"Name":"\u4F60\u597D"},但我想要{"Name":"你好"}

我在https://dotnetfiddle.net/w73vnO创建了一个代码段,请帮助我。

3 个答案:

答案 0 :(得分:8)

您需要设置JsonSerializer选项以不对那些字符串进行编码。

GetKeyboardLayout(GetWindowThreadProcessId(::GetForegroundWindow(), 0))

然后,您在调用JsonSerializerOptions jso = new JsonSerializerOptions(); jso.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping; 方法时通过此选项。

Serialize

完整代码:

var s = JsonSerializer.Serialize(a, jso);        

结果:

enter image description here

如果需要在控制台中打印结果,则可能需要安装其他语言。请参阅here

答案 1 :(得分:3)

您可以使用:System.Text.RegularExpressions.Regex.Unescape(string) 对 unicode 字符进行转义。 https://docs.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.unescape

更新原始问题的示例:

using System;
using System.Text.Json;

public class Program
{
    public static void Main()
    {
            var a = new A{Name = "你好"};
            var s = JsonSerializer.Serialize(a);
        
            var unescaped = System.Text.RegularExpressions.Regex.Unescape(s);

            Console.WriteLine(s);
            Console.WriteLine(unescaped);
        }
}

class A {
    public string Name {get; set;}
}

输出:

{"Name":"\u4F60\u597D"}
{"Name":"你好"}

答案 2 :(得分:2)

要更改JsonSerializer的转义行为,您可以通过在JavascriptEncoder上设置JsonSerializer属性,将自定义Encoder传递给JsonSerializerOptions

https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.encoder?view=netcore-3.0#System_Text_Json_JsonSerializerOptions_Encoder

默认行为的设计考虑了安全性,而JsonSerializer的转义符用于深度防御。

如果您要查找的是转义特定非拉丁语言的某些“字母数字”字符,我建议您改为使用JavascriptEncoder工厂方法而不是使用Create UnsafeRelaxedJsonEscaping编码器。

JsonSerializerOptions options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs)
};

var a = new A { Name = "你好" };
var s = JsonSerializer.Serialize(a, options);
Console.WriteLine(s);

这样做可以确保某些安全措施,例如,HTML敏感字符将继续被转义。

我要谨慎使用 System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,因为它会尽量避免转义(这就是名称中“不安全”的原因)。如果您要创建的JSON写入磁盘上的UTF-8编码文件,或者它是Web请求的一部分,该部分明确将字符集设置为utf-8(并且可能不会原样嵌入HTML组件中),那么可以使用它。

请参阅API文档中的“备注”部分: https://docs.microsoft.com/en-us/dotnet/api/system.text.encodings.web.javascriptencoder.unsaferelaxedjsonescaping?view=netcore-3.0#remarks

如果您希望/需要所有语言都无法转义,则还可以考虑指定UnicodeRanges.All。这样仍然可以转义某些容易引起安全漏洞的ASCII字符。

JsonSerializerOptions options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
};

有关更多信息和代码示例,请参见https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?view=netcore-3.0#customize-character-encoding

See the Caution Note