C# 为什么JsonConvert.DeserializeObject不使用指定的JsonConverter?

C# 为什么JsonConvert.DeserializeObject不使用指定的JsonConverter?,c#,json,json.net,deserialization,C#,Json,Json.net,Deserialization,我已经编写了一个自定义的JsonConverter,我可以将它分配给JsonSerializerSettings,并与JsonConvert.DeserializeObject的通用覆盖一起使用,很好: var settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, Converters = new List<JsonConverter>() { new My

我已经编写了一个自定义的
JsonConverter
,我可以将它分配给
JsonSerializerSettings
,并与
JsonConvert.DeserializeObject
的通用覆盖一起使用,很好:

var settings = new JsonSerializerSettings()
{
    TypeNameHandling = TypeNameHandling.All,
    Converters = new List<JsonConverter>() { new MyConverter() }
};
var x = JsonConvert.DeserializeObject<MyType>(input, settings);
输出:

Creating Example...
...Example Ctor: d860aa00-4493-4ab0-b681-f0af7b123212

Serializing e1...
e1: {"$type":"UnitTests.Serialization.Example, UnitTests","ExampleProp":"some value"}

Deserializing e2 - using DeserializeObject<Example>...
...ExampleConverter.ReadJson...
...Example Ctor: 00000000-0000-0000-0000-000000000000
e2: {"$type":"UnitTests.Serialization.Example, UnitTests","ExampleProp":"some value"}

Deserializing e3 - using DeserializeObject...
...Example Default Ctor...
e3: {"$type":"UnitTests.Serialization.Example, UnitTests","ExampleProp":"some value"}
正在创建示例。。。
…示例:d860aa00-4493-4ab0-b681-f0af7b123212
序列化e1。。。
e1:{“$type”:“UnitTests.Serialization.Example,UnitTests”,“ExampleProp”:“some value”}
反序列化e2-使用反序列化对象。。。
…ExampleConverter.ReadJson。。。
…示例:00000000-0000-0000-0000-000000000000
e2:{“$type”:“UnitTests.Serialization.Example,UnitTests”,“ExampleProp”:“some value”}
反序列化e3-使用反序列化对象。。。
…示例默认Ctor。。。
e3:{“$type”:“UnitTests.Serialization.Example,UnitTests”,“ExampleProp”:“some value”}

编辑:我也发现了这一点,但答案似乎是错误的:

对于我的特定用例,以下结果是正确的:

public object DeserializeFromTypedString(string input, JsonSerializerSettings settings)
{
    var r = new Regex(@"^\{\s*""\$type"":\s*""([^""]+)""");

    var m = r.Match(input);
    if (m.Success)
    {
        var t = Type.GetType(m.Groups[1].Value);
        return Newtonsoft.Json.JsonConvert.DeserializeObject(input, t, settings);
    }
    else
    {
        throw new Exception("$type not found!");
    }
}
其思想是手动解析
$type
定义的字符串,解析类型并使用该类型调用相应的
反序列化对象
重载

这对我来说已经足够好了,因为在我的特定用例中,我总是将JSON作为表示一个根对象(而不是数组)的字符串(而不是流或JToken)。该解决方案可以进行相应调整,但我仍然希望有更好/更清洁的解决方案

如果我在上面的例子中添加方法并交换相应的行

Console.WriteLine("\nDeserializing e3 - using DeserializeFromTypeString...");
var e3 = DeserializeFromTypedString(json, readSettings);
…输出是(正确的):

正在创建示例。。。
…示例:b5af2c3f-1c03-49d8-85c6-f3ff60c9f711
序列化e1。。。
e1:{“$type”:“UnitTests.Serialization.Example,UnitTests”,“Guid”:“b5af2c3f-1c03-49d8-85c6-f3ff60c9f711”,“ExampleProp”:“某些值”}
反序列化e2-使用反序列化对象。。。
…ExampleConverter.ReadJson。。。
…示例:00000000-0000-0000-0000-000000000000
e2:{“$type”:“UnitTests.Serialization.Example,UnitTests”,“Guid”:“00000000-0000-0000-0000-000000000000”,“ExampleProp”:“some value”}
反序列化e3-使用反序列化FromTypedString。。。
…ExampleConverter.ReadJson。。。
…示例:00000000-0000-0000-0000-000000000000
e3:{“$type”:“UnitTests.Serialization.Example,UnitTests”,“Guid”:“00000000-0000-0000-0000-000000000000”,“ExampleProp”:“some value”}

请注意,在这两种反序列化情况下,
ExampleConverter.ReadJson
exampleCtor
的输出都表明我的自定义转换器确实在使用中。(我也在实际代码中使用嵌套对象成功地测试了它。)

您能添加最少的类和示例json字符串来演示这个问题吗,特别是
CanConvert
方法。基本问题是在反序列化过程中,调用
CanConvert
时使用声明的类型而不是实际的类型,因为
“$type”
属性尚未读取(因为它需要在
ReadJson()
中处理)。看一看,并寻找解决办法。纳闷:为什么要投反对票?
Console.WriteLine("\nDeserializing e3 - using DeserializeFromTypeString...");
var e3 = DeserializeFromTypedString(json, readSettings);
Creating Example...
...Example Ctor: b5af2c3f-1c03-49d8-85c6-f3ff60c9f711

Serializing e1...
e1: {"$type":"UnitTests.Serialization.Example, UnitTests","Guid":"b5af2c3f-1c03-49d8-85c6-f3ff60c9f711","ExampleProp":"some value"}

Deserializing e2 - using DeserializeObject<Example>...
...ExampleConverter.ReadJson...
...Example Ctor: 00000000-0000-0000-0000-000000000000
e2: {"$type":"UnitTests.Serialization.Example, UnitTests","Guid":"00000000-0000-0000-0000-000000000000","ExampleProp":"some value"}

Deserializing e3 - using DeserializeFromTypedString...
...ExampleConverter.ReadJson...
...Example Ctor: 00000000-0000-0000-0000-000000000000
e3: {"$type":"UnitTests.Serialization.Example, UnitTests","Guid":"00000000-0000-0000-0000-000000000000","ExampleProp":"some value"}