将对象序列化为已包含一个JSON属性的JSON

时间:2015-07-03 05:59:07

标签: c# .net asp.net-web-api json.net

为了提高性能,我将一个更大的操作的结果作为JSON缓存在一个表中 - 与一个键列一起确定要返回哪一行。所以数据看起来像这样:

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

因此,我检索的对象具有int .Id和string .Json属性。当使用Id返回这样的对象时,我首先需要反序列化JSON - 以便正确地重新序列化。如果我不首先反序列化它,我最终得到一个带引号的字符串,即我的返回对象看起来像这样

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

相反,我需要:

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

有没有办法告诉" Json.Net序列化程序直接输出.Json属性而不序列化 - 同时序列化其他属性?

2 个答案:

答案 0 :(得分:6)

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

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

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

你使用这样的代码进行序列化:

    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 可以满足我们的需求:

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);
    }
}

答案 1 :(得分:0)

基于answer by Alex和Shahin的评论,我对转换器做了一些改进,并实现了读取器也可以以其他方式工作(从JToken解析回string属性):

public sealed class RawDataJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(string);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var tokenReader = reader as JTokenReader;
        var data = tokenReader.CurrentToken.ToString(Formatting.None);
        return data;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteToken(JsonToken.Raw, value);
    }
}
相关问题