反序列化运行时创建的类

时间:2014-11-25 22:52:33

标签: c# json.net deserialization

我正在尝试使用C#和JSON.net反序列化运行时创建的类型,但它会引发解析类型异常。

我有一个空的BaseElement类,其中所有运行时创建的类型都继承,所有类型都保证在反序列化过程之前创建,并且我使用TypeNameHandling = TypeNameHandling.All设置进行序列化和反序列化。

创建类的过程就是这个(简化为一个例子):

        AssemblyName asmName = new AssemblyName();
        asmName.Name = "RaspElementTypes";
        AssemblyBuilder asmBuild = Thread.GetDomain().DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);

        ModuleBuilder modBuild = asmBuild.DefineDynamicModule("TypeModule", "RaspElementTypes.dll");   

        TypeBuilder tb = modBuild.DefineType("ClassInfo", TypeAttributes.Class, typeof(BaseElement));

        //Add properties, functions, etc

        Type finalType =  tb.CreateType();
        var item = (finalType)Activator.CreateInstance(tType);

序列化/反序列化是这样的:

        //Data is a BaseElement[] array with the ClassInfo instances

        //Serialize

        JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
        string res = JsonConvert.SerializeObject(Data, Formatting.Indented, settings);

        //Deserialize

        var deser = JsonConvert.DeserializeObject <BaseElement[]>(res, settings);

确切的错误是:

Newtonsoft.Json.dll中发生未处理的“Newtonsoft.Json.JsonSerializationException”类型异常 附加信息:在JSON'ClassInfo,RaspElementTypes'中指定的错误解析类型。路径'$ values [0]。$ type'。

关于如何反序列化运行时创建类型的任何想法?

感谢。

1 个答案:

答案 0 :(得分:3)

好吧,发现它,只需要创建一个SerializationBinder来提供正确的类型。

在精确的情况下,活页夹看起来像这样:

class binder : SerializationBinder
{
    Type[] types;
    public binder(Type[] Types)
    {
        types = Types;
    }

    public override Type BindToType(string assemblyName, string typeName)
    {
        if(assemblyName == "RaspElements")
        {

            var type = types.Where(t => t.Name == typeName).FirstOrDefault();

            if (type != null)
                return type;

        }
        return Type.GetType(typeName + ", " + assemblyName);
    }
}

反序列化的过程改为:

//runtimeTypes is a Type[] with all the runtime generated types, data is the serialized string

JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, Binder = new binder( runtimeTypes ) };

var deser = JsonConvert.DeserializeObject <BaseElement[]>(data, settings);

希望它可以帮助处于相同情况的人。

干杯