我正在使用 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/