Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Json.NET反序列化到接口实现_C#_Json_Interface_Json.net_Json Deserialization - Fatal编程技术网

C# Json.NET反序列化到接口实现

C# Json.NET反序列化到接口实现,c#,json,interface,json.net,json-deserialization,C#,Json,Interface,Json.net,Json Deserialization,我正在尝试使用序列化一个类,以便通过http请求进行传输。这是一个客户端-服务器测试程序,它共享一些公共类文件。这些文件是一个接口(ITestCase)和该接口的实现(TestPicture,TestVideo) 在同一个应用程序中序列化和反序列化下面的testCase效果很好,可能是因为Json.NET代码都包含在一个程序集中。当我序列化testCase时,将其发送到服务器,然后尝试反序列化,我得到了错误 “JSON'com.test.testcases.TestPicture,Graphic

我正在尝试使用序列化一个类,以便通过http请求进行传输。这是一个客户端-服务器测试程序,它共享一些公共类文件。这些文件是一个接口(
ITestCase
)和该接口的实现(
TestPicture
TestVideo

在同一个应用程序中序列化和反序列化下面的
testCase
效果很好,可能是因为Json.NET代码都包含在一个程序集中。当我序列化
testCase
时,将其发送到服务器,然后尝试反序列化,我得到了错误

“JSON'com.test.testcases.TestPicture,Graphics Tester'中指定的错误解析类型。路径“$type”,第2行,位置61”

具有类型为JsonSerializationException的内部异常,带有消息

“无法加载程序集‘图形检测仪’。”

在中,生成Json时,$type值为“$type”:“Newtonsoft.Json.Samples.Stockholder,Newtonsoft.Json.Tests”。第二个参数似乎是按名称空间引用相关类,而不是按项目名称(即Graphics Tester),因为它发生在我的实例中

既然两个项目都共享必需的类,而且文件位于同一名称空间中,为什么Json.NET要查找程序集而不是类本身

下面是我的代码的框架;由于细节对解决问题没有帮助,所以建议使用细节。显示的是接口以及该接口的两个实现。还显示了序列化和反序列化操作以及生成的Json

ITestCase testCase = new TestPicture("test.jpg")

string json = JsonConvert.SerializeObject(testCase, Formatting.Indented, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Objects,
});

ITestCase instance = JsonConvert.DeserializeObject<ITestCase>(json, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Objects,
});


//value in variable json after serialisation
//{
//  "$type": "com.test.testcases.TestPicture, Graphics Tester",
//  "filename": "test.jpg",
//  "testPoints": null
//}
我的解决方案:


有一个比我想象的更简单的解决方案。这不是最优的,但确实有效。我更倾向于把它归类为一种变通方法或黑客。通过更改项目属性并将程序集名称设置为在两个项目中相同,它将查找项目中已包含的类,从而创建Json字符串指定的对象。

使用
$type
编码完全限定的类型名称,如果客户机和服务器不使用同一个项目来定义这些类型(即,如果每个项目都自己定义类型而不是引用公共程序集),则它们之间的差异将有所不同

在您的情况下,在客户端中,完全限定的名称是
com.test.testcases.TestPicture,Graphics Tester
,但是当它到达服务器时,服务器找不到任何名为
Graphics Tester
的程序集

您可以通过以下两种方法之一解决此问题:

  • 为可序列化类型定义公共程序集,并从客户端和服务器引用它
  • 在客户机和服务器中分别定义类型,并通过提供自定义to自定义Json.NET的类型解析,您可以在其中实现自己的逻辑
    谢谢我试图避免使用另一个二进制文件,因为我正处于一种特殊情况,即使用Mono使我的应用程序跨平台。有关我的解决方案,请参见上面的编辑。我强烈建议您使用自定义
    SerializationBinder
    ,而不是更改程序集名称。编写一个SerializationBinder来查找仅基于类型名的类型相对容易(例如“在当前程序集中查找具有此名称的类型”),它不需要另一个二进制文件,而且与更改一个项目的名称以匹配另一个项目相比,它不太麻烦。
    namespace com.test.testcases
    {
        interface ITestCase
        {
            void Run();
            bool Verify();
        }
    }
    
    namespace com.test.testcases
    {
        class TestPicture : ITestCase {}
    }
    
    namespace com.test.testcases
    {
        class TestVideo : ITestCase {}
    }