序列化对象以JSON已经包含了一个JSON属性属性、对象、序列化、包含了

2023-09-03 06:49:30 作者:该用户身份不明

为了提高性能,我已经缓存的较大操作为JSON在表中的结果 - 一个键列,以确定哪些行(多个)返回在一起。因此,数据看起来有些像这样的:

In order to increase performance, I have cached the result of a larger operation as JSON in a table - together with a key column to determine which row(s) to return. So the data looks some like this:

Id   Json
---- ---------
1    {"property": "data", "...": "..."}
2    {"property": "data", "...": "..."}

因此​​,我检索对象的属性诠释 .ID 和字符串 .Json 。当返回这样一个对象的ID,我首先需要反序列化JSON - 这样它才能正确重新序列。如果我不先反序列化,我结束了一个引号的字符串,也就是我回来的对象是这样的

Hence, my retrieved object has the properties int .Id and string .Json. When returning such an object with the Id, I first need to deserialize the JSON - so that it gets properly re-serialized. If I don't deserialize it first, I end up with a quoted string, i.e. my return object would look like this

{
  "id": 1,
  "json": "{\"property\": \"data\", ...
}

相反,我需要:

Instead, I need:

{
  "id": 1,
  "json": {
      "property": "data", 
      ...
  }
}

有没有办法来告诉Json.Net串行输出 .Json 属性的情况下直接序列 - 序列化时的其他属性。

Is there a way to "tell" the Json.Net serializer to output the .Json property directly without serializing - while serializing the other properties?

推荐答案

假设你有一个这样的结构序列:

Assuming you have a structure like this for serializing:

public class Record
{
    [JsonProperty("id")]
    public int Id
    {
        get;
        set;
    }

    [JsonProperty("json")]
    [JsonConverter(typeof(SpecialJsonConverter))]
    public string Json
    {
        get;
        set;
    }
}

和使用code这样的序列化:

And you use code like this for serialization:

    var data = new []
    { 
        new Record() { Id=1, Json = "{\"property\":\"data\"}" }, 
        new Record() { Id=2, Json = "{\"property\":\"data2\", \"property2\":[1, 2, 3]}" }
    };

    var serialized = JsonConvert.SerializeObject(data);
    Console.WriteLine(serialized);

您只需要编写一个适当的转换器的的的Json 的属性。幸运的是,在 JsonWriter 的方法的 WriteToken 的类,它可以成为我们的需要:

All you need is to write a proper converter for the Json property. Luckily there is a method WriteToken in the JsonWriter class that could serve our needs:

public sealed class SpecialJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var reader = new JsonTextReader(new StringReader(value.ToString()));
        writer.WriteToken(reader);
    }
}