System.Runtime.Serialization.SerializationException:无法找到程序集MyAssembly

Gee*_*esu 7 c# serialization

所以我在这个主题上发现了一堆线索,但我认为我找不到适用的线程.

基本上我的.exe加载一个.dll(MyAssembly)文件,它执行序列化和加载.显然它序列化很好.

但是,当我在MyAssembly.dll文件中反序列化文件时,它会爆炸,并显示此帖子标题中的错误.

有人有主意吗?我不明白它怎么找不到调用代码的程序集!

我的代码:

// deserialize


 using (var target = new System.IO.FileStream(Path, System.IO.FileMode.OpenOrCreate))
 {
     var bin = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
     var Obj = bin.Deserialize(target);
     if (Obj != null)
     {
         ObjectToStore = (ObjectTypeInMyAssembly)Obj;
     }
 }

// serialize
 using (var target = new System.IO.FileStream(Path, System.IO.FileMode.OpenOrCreate))
 {
     var bin = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
     bin.Serialize(target, ObjectToStore);
 }
Run Code Online (Sandbox Code Playgroud)

Roa*_*ump 8

DLL是否与EXE在同一个文件夹中?
我看到你序列化/反序列化DLL中的对象("MyAssembly").反序列化时,格式化程序从序列化数据中确定类型的名称,并尝试在主可执行文件夹(即EXE文件夹)中的程序集中查找此类型.
解决方案 - 将DLL移动到EXE文件夹.有一种方法可以使格式化程序在另一个程序集中搜索,捕获事件AppDomain.AssemblyResolve并返回DLL.请参阅MSDN.


小智 6

好吧,我使用了一个有效的技巧!

sealed class CustomizedBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        Type returntype = null;
        string sharedAssemblyName = "SharedAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
        assemblyName = Assembly.GetExecutingAssembly().FullName;
        typeName = typeName.Replace(sharedAssemblyName, assemblyName);
        returntype =
                Type.GetType(String.Format("{0}, {1}",
                typeName, assemblyName));

        return returntype;
    }

    public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        base.BindToName(serializedType, out assemblyName, out typeName);
        assemblyName = "SharedAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
    }
}
Run Code Online (Sandbox Code Playgroud)

使用binder作为二进制格式化程序,如下所示:

BinaryFormatter bf = new BinaryFormatter();
bf.Binder = new CustomizedBinder();
Run Code Online (Sandbox Code Playgroud)


SAS*_*ter 0

我在序列化和反序列化的代码中看到的是使用 System.IO.Path 类而不是文件的实际路径。我通常按​​如下方式执行:

    static void Main(string[] args)
    {
        string filepath = @"C:\FileLocation\";
        string filename = "datasaved.bin";
        MyClass something = new MyClass();

        // serialize
        using ( FileStream strm = File.OpenWrite(Path.Combine(filepath, filename)))
        {
            BinaryFormatter ser = new BinaryFormatter();
            ser.Serialize(strm, something);
        }

        // deserialize
        using (FileStream strm = File.OpenRead(Path.Combine(filepath, filename)))
        {
            BinaryFormatter ser = new BinaryFormatter();
            something = ser.Deserialize(strm) as MyClass;
        }
    }
Run Code Online (Sandbox Code Playgroud)

请注意两件事:执行反序列化 as将处理为 null 或不是预期类型的​​对象。我也不会滥用 var 的使用。