覆盖ASP.NET Core newtonsoft.json,能够处理继承



考虑下一个代码段:

    static void Main(string[] args)
    {
        var classes = new Classes()
        {
            Instances = new A[]{
                new B
                {
                    BirthDate = DateTime.Now,
                    Name = "B1",
                    SomethingElse = "Test"
                },
                new C
                {
                    Name = "C1",
                    SomethingElse1 = "Test2",
                    SomethingElse2 = "Test3",
                }
            }
        };
        var serialized = JsonConvert.SerializeObject(classes);
        var deserialized = JsonConvert.DeserializeObject<Classes>(serialized);
    }
}
public class Classes
{
    public A[] Instances { get; set; }
}
public enum ClassType
{
    B = 1,
    C = 2
}
public class A
{
    public string Name { get; set; }
    public virtual ClassType ClassType { get; }
}
public class B : A
{
    public string SomethingElse { get; set; }
    public DateTime BirthDate { get; set; }
    public override ClassType ClassType => ClassType.B;
}
public class C : A
{
    public string SomethingElse1 { get; set; }
    public string SomethingElse2 { get; set; }
    public override ClassType ClassType => ClassType.C;
}

我需要将自己的逻辑注入避难所如何用继承来处理类。在这种情况下,我想根据JSON中的ClasStype属性做出决定。有什么想法/提示如何做?

顺便说一句。我知道我可以使用newtonsoft.json TypeNameHandling = TypeNameHandling.All的功能,但是由于数据是从第三方系统发送的,因此我无法控制序列化过程。我控制的唯一一件事是挑选部分。

由于您不能使用TypeNameHandling,因此必须先解析它,找到类型,然后进行挑选。

喜欢:

var jObj = Newtonsoft.Json.Linq.JObject.Parse(serialized);
var instances = jObj["Instances"].AsJEnumerable();
var myCol = new List<A>();
myCol.AddRange(instances.Select(x => (x["ClassType"] as JToken)
.ToObject<ClassType>() == ClassType.B ?
  (x as JObject).ToObject<B>() : 
  (x as JObject).ToObject<C>());

感谢@zaitsman和@davidg我提出了对我有用的解决方案。在这里是:

public class AClassConverter : JsonConverter
{
    private readonly Type[] _types;
    public AClassConverter(params Type[] types)
    {
        _types = types;
    }
    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)
    {
        var jObj = JObject.Load(reader);
        var classType = jObj["ClassType"].ToObject<ClassType>();
        return classType == ClassType.B ? 
            (A)jObj.ToObject<B>() : 
            (A)jObj.ToObject<C>();
    }
    public override bool CanRead => true;
    public override bool CanWrite => false;
    public override bool CanConvert(Type objectType)
    {
        return _types.Any(t => t == objectType);
    }
}

何时进行审理:

var deserialized = JsonConvert.DeserializeObject<Classes>(serialized, new AClassConverter(typeof(A)));

相关内容

  • 没有找到相关文章

最新更新