c# - 有没有办法让 Newtonsoft.Create 在界面上调用您的自定义创建方法?

标签 c# interface json.net deserialization hangfire

我正在使用 Hangfire 来运行我的自定义 interface 的多个任务,我们称它为 IType。但是,由于 Hangfire 序列化了该方法,从而破坏了该类型的实例,因此当它尝试调用它时,我收到如下错误消息:

Newtonsoft.Json.JsonSerializationException: Could not create an instance of type IType. Type is an interface or abstract class and cannot be instantiated. Path 'Something', line 1, position 17. at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(...

我认为解决这个问题的一种方法是让作为我的接口(interface)实例的每个都可以存储它的完全限定域名,然后我可以使用 reflection 返回它需要的类型,唯一的问题是我不知道如何获取 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject()调用我的反序列化方法。是否需要一些属性或一些特定的方法名称才能使这项工作正常进行?

最佳答案

您需要指定包含合适的 TypeNameHandling 值的 JsonSerializerSettings。这会将 JSON 中的完全限定名称嵌入到 $type 属性中,然后可以使用该属性进行反序列化。这是一个完整的示例:

using System;
using Newtonsoft.Json;

interface IFoo
{
    void Method();
}

class Foo1 : IFoo
{
    public string Name { get; set; }
    public void Method() => Console.WriteLine("Method in Foo1");
}

class Foo2 : IFoo
{
    public int Value { get; set; }
    public void Method() => Console.WriteLine("Method in Foo2");
}

class Root
{
    public IFoo First { get; set; }
    public IFoo Second { get; set; }
}

class Test
{
    static void Main()
    {
        Root root = new Root
        { 
            First = new Foo1 { Name = "Fred" },
            Second = new Foo2 { Value = 10 }
        };
        var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
        string json = JsonConvert.SerializeObject(root, settings);

        Console.WriteLine(json);

        Root root2 = JsonConvert.DeserializeObject<Root>(json, settings);
        root2.First.Method();
        root2.Second.Method();
    }
}

输出,显示 JSON 和 Root 中的接口(interface)属性已被适当反序列化的事实:

{"$type":"Root, Test","First":{"$type":"Foo1, Test","Name":"Fred"},"Second":{"$type":"Foo2, Test","Value":10}}
Method in Foo1
Method in Foo2

您可能想使用其他 TypeNameHandling 值来代替 All - 请参阅 the documentation了解详情。

关于c# - 有没有办法让 Newtonsoft.Create 在界面上调用您的自定义创建方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52051399/

相关文章:

asp.net-mvc - 从 Web api + AngularJS 中的 JSON 中删除 ↵

c# - 反序列化 Microsoft.OData.Edm.Date

c# - 我如何从 Telegram Bot 创建私有(private)消息?

c# - 限制应用程序的 CPU 使用率

java - 我不明白 'this' 与父类(super class)一起使用

c# - JSON.NET 反序列化为带有 Type 参数的对象

c# - 如何在 vs2012 中将发布配置文件添加到新的 sln?

c# - 在 MS 图表中添加注释(例如 (10, 20) (20, 39) 等)和水平滚动条

java - 创建一个添加方法,如果重复,则不会添加到列表中?

c# - 在 f# 中实现接口(interface)