簡體   English   中英

如何指示Json.NET將接口類型轉換為具體類型而無需訪問序列化程序?

[英]How can I instruct Json.NET to convert an interface type to a concrete type without access to the serializer?

我的問題是我需要將JSON反序列化為包含接口類型對象的類型,因此需要指導Json.NET如何轉換該接口類型,但不能直接控制Newtonsoft.Json.Deserializer 反序列化由框架代碼(即HttpContent.ReadAsAsync <T>)間接處理。

如何在不將轉換器直接添加到JsonSerializer.Converters情況下指定從接口類型到具體類型的轉換? 如果我在接口定義上使用[JsonConverter]屬性,則還會調用該轉換器來實現該接口的實現(即,我要轉換為的具體類型)。

在下面的代碼示出了嘗試將反序列化相同的JSON首先將一個C#控制台程序Parent2類,然后將Parent1類,指示Json.NET到轉換IChild1接口類型到Child1經由具體類型JsonConverterAttribute 反序列化到Parent2的作品,因為我添加ChildConverter直接serializer.Converters ,而反序列化到Parent1導致堆棧溢出異常,由於ChildConverter.Deserialize被稱為甚至對於Child1類型。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;

namespace TestConsole
{
    [JsonConverter(typeof(ChildConverter))]
    interface IChild1
    {
        string Name { get; set; }
    }

    class Child1 : IChild1
    {
        public string Name { get; set; }
    }

    class Parent1
    {
        public IEnumerable<IChild1> Children { get; set; }
    }

    interface IChild2
    {
        string Name { get; set; }
    }

    class Child2 : IChild2
    {
        public string Name { get; set; }
    }

    class Parent2
    {
        public IEnumerable<IChild2> Children { get; set; }
    }

    class ChildConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(IChild1) || objectType == typeof(IChild2);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (objectType == typeof(IChild1))
                return serializer.Deserialize<Child1>(reader);
            return serializer.Deserialize<Child2>(reader);
        }

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

    class Program
    {
        static void Main(string[] args)
        {
            var json = "{'Children': [{'Name': 'Child1'}, {'Name': 'Child2'}]}";

            var serializer = new JsonSerializer();

            serializer.Converters.Add(new ChildConverter());
            var obj = serializer.Deserialize(new StringReader(json), typeof(Parent2));

            serializer = new JsonSerializer();
            obj = serializer.Deserialize(new StringReader(json), typeof(Parent1));
        }
    }
}

我找到了解決我特定問題的解決方案,即調用HttpContent.ReadAsAsync <T>並反序列化JSON響應。 雖然我的解決方案無法解決在不訪問序列化程序的情況下配置Json.NET類型轉換的一般問題,但確實可以解決我的特殊問題。 我發現HttpContent.ReadAsync<T>接受IEnumerable<MediaTypeFormatter> ,該序列用於反序列化響應。 在這里,可以傳遞一個JsonMediaTypeFormatter ,該JsonMediaTypeFormatter已使用您選擇的JsonConverter (在我的示例中為ChildConverter )進行了配置。

var formatter = new JsonMediaTypeFormatter();
formatter.SerializerSettings.Converters.Add(new ChildConverter());
var obj = await resp.Content.ReadAsAsync<T>(new MediaTypeFormatter[] {formatter});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM