47

使用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创建了一个代码片段,
请帮助我。

4

4 回答 4

65

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

JsonSerializerOptions jso = new JsonSerializerOptions();
jso.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;

Serialize然后在调用方法时传递此选项。

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

完整代码:

JsonSerializerOptions jso = new JsonSerializerOptions();
jso.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;

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

结果:

在此处输入图像描述

如果您需要在控制台中打印结果,您可能需要安装其他语言。请参考这里

于 2019-09-19T03:38:38.787 回答
30

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

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

请参阅注意事项

于 2019-12-10T04:24:17.230 回答
6

您可以使用: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":"你好"}
于 2021-06-11T10:55:17.533 回答
1

利用:

JsonSerializerOptions options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
};
于 2021-10-28T10:29:06.533 回答