Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
459 views
in Technique[技术] by (71.8m points)

c# - Deserializing a list of interfaces with a custom JsonConverter?

I have a List<ISomething> in a json file and I can't find an easy way to deserialize it without using TypeNameHandling.All (which I don't want / can't use because the JSON files are hand-written).

Is there a way to apply the attribute [JsonConverter(typeof(MyConverter))] to members of the list instead to the list?

{
    "Size": { "Width": 100, "Height": 50 },
    "Shapes": [
        { "Width": 10, "Height": 10 },
        { "Path": "foo.bar" },
        { "Width": 5, "Height": 2.5 },
        { "Width": 4, "Height": 3 },
    ]
}

In this case, Shapes is a List<IShape> where IShape is an interface with these two implementors: ShapeRect and ShapeDxf.

I've already created a JsonConverter subclass which loads the item as a JObject and then checks which real class to load given the presence or not of the property Path:

var jsonObject = JObject.Load(reader);

bool isCustom = jsonObject
    .Properties()
    .Any(x => x.Name == "Path");

IShape sh;
if(isCustom)
{
    sh = new ShapeDxf();
}
else
{
    sh = new ShapeRect();
}

serializer.Populate(jsonObject.CreateReader(), sh);
return sh;

How can I apply this JsonConverter to a list?

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In your class, you can mark your list with a JsonProperty attribute and specify your converter with the ItemConverterType parameter:

class Foo
{
    public Size Size { get; set; }

    [JsonProperty(ItemConverterType = typeof(MyConverter))]        
    public List<IShape> Shapes { get; set; }
}

Alternatively, you can pass an instance of your converter to JsonConvert.DeserializeObject, assuming you have implemented CanConvert such that it returns true when objectType == typeof(IShape). Json.Net will then apply the converter to the items of the list.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...