locked
WCF service streaming. Exception: "Unable to find assembly" RRS feed

  • Question

  • Good day.
    When transferring data from a WCF service in the stream through the BinaryFormatter, when deserialize on the client getting exception "Unable to find assembly".

    on the service:

    [ServiceContract]
        public interface IP
        {
            [OperationContract]
            Stream get_o();
        }
    
    public class P : IP
        {
            public Stream get_o()
            {
                MemoryStream stream = new MemoryStream();
                BinaryFormatter formatter = new BinaryFormatter();
                using (EntityModelContainer context = new EntityModelContainer())
                {
                    formatter.Serialize(stream, context.t_O.ToArray());
                    stream.Seek(0, SeekOrigin.Begin);
                    return stream;
                }
            }
        }
    


    on the client:

    using (PClient proxy = new PClient())
        {
            Stream stream = proxy.get_o();
            BinaryFormatter formatter = new BinaryFormatter();
            t_O[] oList = (t_O[])(formatter.Deserialize(stream));
            this.dataGridView.DataSource = oList;
        }
    
     

    In Google found a solution to override BindToType

    sealed class DeserializationBinder : SerializationBinder
        {
            public override Type BindToType(string assemblyName, string typeName)
            {
                Type typeToDeserialize = null;
                String currentAssembly = Assembly.GetExecutingAssembly().FullName;
                assemblyName = currentAssembly;
                typeToDeserialize = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));
                return typeToDeserialize;
            }
        } 


    but how to get the client this DeserializationBinder to initialize formatter

    BinaryFormatter formatter = new BinaryFormatter()
        {
            Binder = new DeserializationBinder()
        };


    i do not understand... Help me please/
    • Edited by Dedyshka Thursday, July 30, 2009 8:40 AM
    Thursday, July 30, 2009 8:38 AM

Answers

  • Hi,

      When serializing an object, the full name of the type and the name of the type's defining assembly are written to the byte stream. By default, the BinaryFormatter and SoapFormatter types output the assembly's full identity, which includes the assembly's file name (without extension), version number, culture, and public key information. However, you can make these formatters write the simple assembly name (just file name; no version, culture, or public key information) for each serialized type by setting the formatter's AssemblyFormat property to FormatterAssemblyStyle.Simple. This read/write property is offered by both the BinaryFormatter and SoapFormatter types.
          When deserializing an object, the formatter first grabs the assembly identity and ensures that the assembly is loaded into the executing AppDomain. If the formatter's AssemblyFormat property is set to FormatterAssemblyStyle.Full (the default), then the assembly is loaded by calling System.Reflection.Assembly's Load method. This method looks in the Global Assembly Cache (GAC) for the specified assembly and then looks in the application's directory. If the assembly can't be found, then an exception is thrown and no more objects can be deserialized.
          However, if the formatter's AssemblyFormat property is set to FormatterAssemblyStyle.Simple, then the assembly is loaded by calling System.Reflection.Assembly's LoadWithPartialName method. This method looks in the application's directory first for a matching assembly. If the application's directory doesn't have a matching assembly, then the GAC is scanned, looking for the highest version numbered assembly with the same file name. However, since no culture or public key information is specified, the assembly loaded is actually undefined and therefore, you should never set the AssemblyFormat property to FormatterAssemblyStyle.Simple when serializing or deserializing a byte stream. Chapter 20 of my book, Applied Microsoft .NET Framework Programming (Microsoft Press, 2002) has more information about Assembly's Load and LoadWithPartialName methods. ref: http://msdn.microsoft.com/en-us/magazine/cc301761.aspx


    Here is alse a detailed discussion on "Unable to find assembly" exception, you might get some hints for your case:

    http://www.west-wind.com/weblog/posts/251.aspx

    Thanks
    Binze
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Bin-ze Zhao Friday, August 7, 2009 10:52 AM
    Wednesday, August 5, 2009 4:12 AM

All replies

  • Hi,

    Actually this is ok:

    BinaryFormatter formatter = new BinaryFormatter() {
        Binder = new DeserializationBinder()
    };
    

    Does it work or not?.

    Regards,
    Rodrigo.
    Thursday, July 30, 2009 1:57 PM
  • Hi,

    Can you please post the full stack trace of the exception you're getting? "Unable to find assembly" usually indicates a problem with the machine configuration, or incorrectly referenced DLLs.

    --Jason

    Tuesday, August 4, 2009 6:30 PM
  • Hi,

      When serializing an object, the full name of the type and the name of the type's defining assembly are written to the byte stream. By default, the BinaryFormatter and SoapFormatter types output the assembly's full identity, which includes the assembly's file name (without extension), version number, culture, and public key information. However, you can make these formatters write the simple assembly name (just file name; no version, culture, or public key information) for each serialized type by setting the formatter's AssemblyFormat property to FormatterAssemblyStyle.Simple. This read/write property is offered by both the BinaryFormatter and SoapFormatter types.
          When deserializing an object, the formatter first grabs the assembly identity and ensures that the assembly is loaded into the executing AppDomain. If the formatter's AssemblyFormat property is set to FormatterAssemblyStyle.Full (the default), then the assembly is loaded by calling System.Reflection.Assembly's Load method. This method looks in the Global Assembly Cache (GAC) for the specified assembly and then looks in the application's directory. If the assembly can't be found, then an exception is thrown and no more objects can be deserialized.
          However, if the formatter's AssemblyFormat property is set to FormatterAssemblyStyle.Simple, then the assembly is loaded by calling System.Reflection.Assembly's LoadWithPartialName method. This method looks in the application's directory first for a matching assembly. If the application's directory doesn't have a matching assembly, then the GAC is scanned, looking for the highest version numbered assembly with the same file name. However, since no culture or public key information is specified, the assembly loaded is actually undefined and therefore, you should never set the AssemblyFormat property to FormatterAssemblyStyle.Simple when serializing or deserializing a byte stream. Chapter 20 of my book, Applied Microsoft .NET Framework Programming (Microsoft Press, 2002) has more information about Assembly's Load and LoadWithPartialName methods. ref: http://msdn.microsoft.com/en-us/magazine/cc301761.aspx


    Here is alse a detailed discussion on "Unable to find assembly" exception, you might get some hints for your case:

    http://www.west-wind.com/weblog/posts/251.aspx

    Thanks
    Binze
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Bin-ze Zhao Friday, August 7, 2009 10:52 AM
    Wednesday, August 5, 2009 4:12 AM