使用不同的propertyValue类型反序列化json

时间:2018-05-16 20:05:19

标签: c#

我想反序列化(以及之后再次序列化)以下Json

{
  "id": "12345",
  "custom_fields": [
      {
        "definition": "field1",
        "value": "stringvalue"
      },      
      {
        "definition": "field2",
        "value": [ "arrayvalue1", "arrayvalue2" ]
      },
      {
        "definition": "field3",
        "value": {
          "type": "user",
          "id": "1245"
        }
      }
    ]
}

值的类型如果不同(field1:string,field2:array,field3:一个额外的嵌套结构)。 这就是我所拥有的:

public class CustomField
{
    public string Definition { get; set; }
    public object Value { get; set; }
}

public class RootObject
{
    public string Id { get; set; }
    public List<CustomField> Custom_fields { get; set; }
}

Value-field被定义为object,但这在再次序列化时会出现问题,尤其是field3的嵌套结构。 我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

您可以为Value媒体资源实施自定义转换器:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Test
{
    public class Program
    {
        static void Main(string[] args)
        {
            var json = 
                @"{
                  ""id"": ""12345"",
                  ""custom_fields"": [
                      {
                        ""definition"": ""field1"",
                        ""value"": ""stringvalue""
                      }, {
                        ""definition"": ""field2"",
                        ""value"": [ ""arrayvalue1"", ""arrayvalue2"" ]
                      }, {
                        ""definition"": ""field3"",
                        ""value"": {
                          ""type"": ""user"",
                          ""id"": ""1245""
                        }
                      }
                    ]
                }";

            var rootObject = JsonConvert.DeserializeObject<RootObject>(json);

            Console.WriteLine(JsonConvert.SerializeObject(rootObject));
        }
    }

    public class RootObject
    {
        [JsonProperty(PropertyName = "id")]
        public string Id { get; set; }

        [JsonProperty(PropertyName = "custom_fields")]
        public List<CustomField> CustomFields { get; set; }
    }

    public class CustomField
    {
        [JsonProperty(PropertyName = "definition")]
        public string Definition { get; set; }

        [JsonProperty(PropertyName = "value")]
        [JsonConverter(typeof(CustomValueConverter))]
        public dynamic Value { get; set; }
    }

    public class CustomValueConverter : JsonConverter
    {
        // By returning false, we let the default `WriteJson` kick in
        public override bool CanWrite => false;

        public override bool CanConvert(Type objectType) 
        {
            return true;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return string.Empty;
            } 

            if (reader.TokenType == JsonToken.String)
            {
                return serializer.Deserialize<string>(reader);
            }

            if (reader.TokenType == JsonToken.StartArray)
            {
                return serializer.Deserialize<string[]>(reader);
            }

            return serializer.Deserialize<Dictionary<string, string>>(reader);
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
}