【问题标题】:Output string property verbatim to prevent double encoding逐字输出字符串属性以防止双重编码
【发布时间】:2015-09-17 10:11:16
【问题描述】:

我有以下代码:

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 的新类型,它包装一个字符串,并为这种新类型提供一个自定义转换器,直接输出该字符串。

【问题讨论】:

  • 我不确定代码的 intent,如果我输入为 "{X: 5}" 并且在 JSON 中我得到没有双引号的值,我会更多困惑。
  • 也许是一个自定义转换器,其 JsonConverter 属性仅应用于该属性?
  • @Habib 我不打算在所有字符串上都有这种行为,只是某些我不想被编码为 javascript 字符串的字符串。
  • 快速简单的方法(是的,它是反序列化然后重新序列化):var data = new { A = JObject.Parse("{X: 5}"), ... }
  • 另外,我假设您发布的内容只是一个示例,但在这种情况下,A 的值实际上不是有效的 JSON。您需要在字符串中引用 "X"。

标签: c# .net json serialization json.net


【解决方案1】:

你可以:

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。

【讨论】:

  • 这正是我需要的,谢谢。我不关心反序列化性能,因为在我的场景中不需要它,但很高兴知道未来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-21
  • 2020-01-04
相关资源
最近更新 更多