逐字输出字符串属性以防止双重编码

本文关键字:编码 输出 字符串 属性 | 更新日期: 2023-09-27 18:00:34

我有以下代码:

var data = new {
    A = "{'"X'": 5}",
    B = new {Y = 6}
};
var json = JsonConvert.SerializeObject(data);

这导致:

{
    "A": "{'"X'": 5}",
    "B": {Y: 6}
}

然而,我需要的是(没有A上的引号):

{
    "A": {"X": 5},
    "B": {"Y": 6}
}

实际上,我的A属性有一个非常复杂的JSON字符串,它已经被另一个系统序列化了。

一个解决方法是先反序列化我的A属性,然后让JSON.NET将其序列化回来,但这是浪费,并且混淆了代码的意图。

如何告诉JSON.NET使用属性的字符串表示进行序列化,而不是为我序列化它?

编辑:

我最初的想法是创建一个名为JsonVerbatim的新类型,它包装一个字符串,并为这个新类型提供一个直接输出该字符串的自定义转换器。

逐字输出字符串属性以防止双重编码

您可以:

public class LiteralStringConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(string);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        object value = serializer.Deserialize(reader);
        string value2 = JsonConvert.SerializeObject(value);
        return value2;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        string str = (string)value;
        writer.WriteRawValue(str);
    }
}

然后

public class MyObject
{
    [JsonConverter(typeof(LiteralStringConverter))]
    public string A { get; set; }
    public object B;
}

然后:

var data = new MyObject
{
    A = "{X: 5}",
    B = new { Y = 6 }
};
var json = JsonConvert.SerializeObject(data);

返回:

var data2 = JsonConvert.DeserializeObject<MyObject>(json);

请注意,虽然序列化现在已经"优化",但反序列化的速度要慢两倍,因为我反序列化为object,然后保留为string