Newtonsoft.json serializing and deserializing base/inheirited where classes are from shared projects

假如想象 提交于 2019-12-06 07:56:29

Thank you @dbc, your suggestion to write a custom SerializationBinder is, as far as I can tell, the best solution to my problem.

I used the KnownTypesBinder as implemented at: https://www.newtonsoft.com/json/help/html/SerializeSerializationBinder.htm

KnownTypesBinder:

public class KnownTypesBinder : ISerializationBinder
    {
        public IList<Type> KnownTypes { get; set; }

        public Type BindToType(string assemblyName, string typeName)
        {
            return KnownTypes.SingleOrDefault(t => t.Name == typeName);
        }

        public void BindToName(Type serializedType, out string assemblyName, out string typeName)
        {
            assemblyName = null;
            typeName = serializedType.Name;
        }
    }

JsonSerializerSettings with the SerializationBinder set to an instance of KnownTypesBinder was used on both the serializing and deserializing endpoints. I probably only need it for the deserializing end, but put it in both for consistency.

settings = new JsonSerializerSettings
{
    TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
    TypeNameHandling = TypeNameHandling.Objects,
    SerializationBinder = new KnownTypesBinder()
};

After creating a settings object then I pass it into the JsonConvert serialization functions.

JsonConvert.DeserializeObject<T>(Encoding.Unicode.GetString(input), settings) 

Also note that KnownTypes in KnownTypesBinder must be prepopulated with all of the non primitive types you will be deserializing.

Edit: I am currently not accepting my own answer because I have no idea how to handle List of complex types. For instance if a Person has a List and a List, what type do you return when the typeName is "List`1" and it could be either one.

Edit The following version of the KnownTypesBinder solved my issues related to Lists of objects.

public class KnownTypesBinder: ISerializationBinder
{
    public IList<Type> KnownTypes { get; set; }

    public Type BindToType(string assemblyName, string typeName)
    {
        return KnownTypes.SingleOrDefault(t => t.UnderlyingSystemType.ToString() == typeName);
    }

    public void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        assemblyName = null;
        typeName = serializedType.UnderlyingSystemType.ToString();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!