自定義JsonConverter,反序列化不符合規範的陣列屬性

風靈使發表於2018-10-13

如果json 字串不符合規範,可以通過自定義jsonconvert 解決

    public class SingleValueArrayConverter<T> : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
 
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            object retVal = new Object();
            if (reader.TokenType == JsonToken.StartObject)
            {
                T instance = (T)serializer.Deserialize(reader, typeof(T));
                retVal = new List<T>() { instance };
            }
            else if (reader.TokenType == JsonToken.StartArray)
            {
                retVal = serializer.Deserialize(reader, objectType);
            }
            return retVal;
        }
 
        public override bool CanConvert(Type objectType)
        {
            return true;
        }
    }  

自定義 jsonConverter的問題記錄

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
 
namespace ConsoleApplication1
{
    public class A
    {
        public string Title = "A Title";
 
        [JsonConverter(typeof(ConsoleApplication1.Program.custConverter))]
        public List<answerBase> baseAnswerList = new List<answerBase>();
    }
 
    public class answerA : answerBase
    {
        public List<int> value = new List<int>() { 1, 2, 3 };
    }
 
    public class answerB : answerBase
    {
        public List<string> Correct = new List<string>() { "1111", "2222" };
        public List<string> Incorrect = new List<string>() { "3333", "4444" };
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings();
            jsonSerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
 
            var test1 = new A();
 
            test1.baseAnswerList.Add(new answerA());
 
            var result = JsonConvert.SerializeObject(test1, jsonSerializerSettings);
 
            var test2 = new A();
 
            test2.baseAnswerList.Add(new answerB());
 
            var result2 = JsonConvert.SerializeObject(test2, jsonSerializerSettings);
 
 
            A a = (A)JsonConvert.DeserializeObject(result, jsonSerializerSettings);
            A a1 = (A)JsonConvert.DeserializeObject(result2, jsonSerializerSettings);
 
            List<A> testAList = new List<A>();
 
            testAList.Add(test1);
            testAList.Add(test2);
 
            var resultList = JsonConvert.SerializeObject(testAList, jsonSerializerSettings);
 
            var deserializeResult = JsonConvert.DeserializeObject(resultList, jsonSerializerSettings);
        }
 
        public class custConverter : JsonConverter
        {
 
            public override bool CanConvert(Type objectType)
            {
                return true;
            }
 
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                bool isError = false;
                try
                {
                    List<int> retValTest1 = new List<int>();
                    retValTest1 = (List<int>)serializer.Deserialize(reader, typeof(List<int>));
                    var t1 = new List<answerBase>();
                    var a1 = new answerA();
                    a1.value = retValTest1;
                    t1.Add(a1);
 
                    return t1;
                }
                catch
                {
                    isError = true;
                }
 
                if (isError)
                {
                    try
                    {
                        var retVal = new List<answerB>();
                        retVal = (List<answerB>)serializer.Deserialize(reader, typeof(List<answerB>));
                        var t = new List<answerBase>();
 
                        foreach (var item in retVal)
                        {
                            t.Add(new answerB()
                            {
                                Correct = item.Correct.Distinct().ToList(),
                                Incorrect = item.Incorrect.Distinct().ToList()
                            });
                        }
 
                        return t;
                    }
                    catch
                    {
                        isError = true;
 
                    }
                }
                return null;
            }
            //public override bool CanRead
            //{
            //    get { return false; }
            //}
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                if (value == null)
                {
                    writer.WriteNull();
                    return;
                }
                bool bValue = false;
 
                answerBase temp = new answerBase();
                if (((List<answerBase>)value).Count() > 0)
                {
                    temp = ((List<answerBase>)value).First();
                    bValue = temp is answerA;
                }
 
                if (bValue)
                {
                    var tempA = temp as answerA;
 
                    writer.WriteStartArray();
 
                    foreach (var item in tempA.value)
                    {
                        writer.WriteValue(item);
                    }
                    writer.WriteEndArray();
 
                }
                else
                {
                    JToken t = JToken.FromObject(value);
                    t.WriteTo(writer);
                }
            }
        }
    }
}

相關文章