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
5.0k views
in Technique[技术] by (71.8m points)

c# - Custom generic json converter not called

I have a custom JsonConverter for a Dictionary with abstract keys and values:

public class DictionaryJsonConverter<TKey, TValue> : JsonConverter<Dictionary<TKey, TValue>>

I use it as follows:

[JsonConverter(typeof(DictionaryJsonConverter<ServerDevice, long>))]
public static Dictionary<ServerDevice, long> KnownServers { get; set; }

But neither the read nor the write method is called. Am I missing something?

Error reproduction example: https://dotnetfiddle.net/2VakI3 (Does not compile in DotNetFiddle)
I do not guarantee that the read or write methods are correct because I never saw a result.


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

1 Reply

0 votes
by (71.8m points)

I believe the issue is that you can't just do JsonConvert.SerializeObject(SomeDictionaryThatHappensToBeInAProperty), because then it doesn't see the JsonConverterAttribute. All it knows is that it has been given a Dictionary from somewhere. As such it will use whichever JsonConverter it has for dictionaries.

Therefore, you need to tell Json.NET which converter to use explicitly. From your comments you appear to have found one way to tell Json.NET which converter to use (by storing the converter in the Converters property of a JsonSerializerSettings instance and giving it as argument to JsonConvert.SerializeObject).


If, however, your property was in a class, and you serialized an instance of that class, it would work fine as you had it, because it will see the attribute on the property and know which JsonConverter to use. For example:

public class Test {
    [JsonConverter(typeof(DictionaryJsonConverter<ServerDevice, long>))]
    public Dictionary<ServerDevice, long> KnownServers { get; set; }
}

...

static void Main(string[] args) {
    Test test = new Test() {
        KnownServers = new Dictionary<ServerDevice, long>() {
            { new ServerDevice() { ID = "a", Name = "A", IPAddress = IPAddress.Any }, 1 },
            { new ServerDevice() { ID = "b", Name = "B", IPAddress = IPAddress.Any }, 2 },
            { new ServerDevice() { ID = "c", Name = "C", IPAddress = IPAddress.Any }, 3 },
        }
    };
    
    // This correctly uses DictionaryJsonConverter for KnownServers
    Console.WriteLine(JsonConvert.SerializeObject(test));
}

This method may not be what you want though because it will obviously serialize the Test object "around" the property as well.


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

...