【发布时间】:2018-02-05 23:16:51
【问题描述】:
所以我有两个类,如下所示。它们都在同一个命名空间和同一个共享项目中。
public class Person{
public string Name{get;set;}
}
public class EmployedPerson : Person{
public string JobTitle{get;set;}
}
当我将这些项目序列化到rabbitmq中时,我将序列化为基类,如下所示:
JsonSerializerSettings settings = new JsonSerializerSettings
{
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
TypeNameHandling = TypeNameHandling.Objects
};
JsonConvert.SerializeObject(input, settings)
但是在反序列化时我遇到了问题。我希望能够执行如下所示的操作,我将反序列化为基类,然后检查它是否是继承类型。
类型检查:
Person person = Deserialize<Person>(e.Body, Encoding.Unicode);
if (person is EmployedPerson)
{
logger.LogInformation("This person has a job!");
}
反序列化设置:
JsonSerializerSettings settings = new JsonSerializerSettings
{
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
TypeNameHandling = TypeNameHandling.Auto
};
反序列化逻辑:
private static T Deserialize<T>(byte[] data, Encoding encoding) where T : class
{
try
{
using (MemoryStream stream = new MemoryStream(data))
using (StreamReader reader = new StreamReader(stream, encoding))
return JsonSerializer.Create(settings).Deserialize(reader, typeof(T)) as T;
}
catch (Exception e)
{
Type typeParameter = typeof(T);
logger.LogError(LogEvent.SERIALIZATION_ERROR, e, "Deserializing type {@TypeName} failed", typeParameter.Name);
logger.LogInformation(Encoding.UTF8.GetString(data));
return default(T);
}
}
结果: 上面的代码失败,因为 $type 属性包含程序集名称,并且在 rabbitmq 的每一端,程序集名称不同,因为类位于共享项目中。
示例错误:
Newtonsoft.Json.JsonSerializationException: Error resolving type specified in JSON 'Shared.Objects.EmployedPerson, Person.Dispatcher'. Path '$type', line 1, position 75. ---> System.IO.FileNotFoundException: Could not load file or assembly 'Person.Dispatcher, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
【问题讨论】:
-
我认为这可能是您问题的答案:stackoverflow.com/questions/12381636/…
-
你可以 1) 写一个custom
SerializationBinder。正如here 所解释的那样,出于安全原因编写自己的对反序列化类型进行清理的活页夹也是一个好主意。 2) 发出您自己的自定义类型属性并使用自定义JsonConverter对其进行解析,如图所示,例如在Json.Net Serialization of Type with Polymorphic Child Object 中。 -
查看 SerializationBinder。
-
我很困惑。如果类型在共享项目中,为什么队列两端的程序集名称不同?
-
因为共享项目不创建自己的程序集。它们被同化到正在使用它的项目中。
标签: c# json serialization json.net shared-project