CSLA 3.8.2 - Odd Serialization Exception

CSLA 3.8.2 - Odd Serialization Exception

Old forum URL: forums.lhotka.net/forums/t/8896.aspx


ErikJL posted on Friday, May 07, 2010

I'm seeing an odd exception that I can't figure out. I have a list class that inherits BusinessListBase<T>, 'PingRequestList', and a class that inherits from BusinessBase<T>, 'PingRequest'. They are located in the assembly 'ETS.PingLibrary.' Using these objects works perfectly in a test form; however, when I use them inside of an add-on to a COM-based application (via the application's SDK (ArcGIS is the app)), I get a Serialization Exception when trying to perform the Save() method of the list object:

"System.Runtime.Serialization.SerializationException: Unable to find assembly 'ETS.PingLibrary"

Stepping into the BusinessListBase.Save() method,  the exception occurrs in the ObjectCloner.Clone() method. It manages to serialize OK, it's on the deserialization that has the problem.

public static object Clone(object obj)
    {
      using (MemoryStream buffer = new MemoryStream())
      {
        ISerializationFormatter formatter =
          SerializationFormatterFactory.GetFormatter();
        formatter.Serialize(buffer, obj);
        buffer.Position = 0;
        object temp = formatter.Deserialize(buffer);    <--- this is where the exception gets thrown
        return temp;
      }
    }

 

I am using CSLA 3.8.2, .NEW 3.5, Visual Studio 2010, and ArcGIS 9.3.1 (the host app).

 

ErikJL replied on Friday, May 07, 2010

I forgot to add that I do have [Serializable()] on the list and items objects as well as their respective criteria objects.

RockfordLhotka replied on Friday, May 07, 2010

This is a known (though obscure) issue with .NET serialization when it is hosted in COM (including IE and many other scenarios).

If you look in the EnterpriseServices data portal host code (in Csla.Server.Hosts) you'll find some code called "serialization workaround". That code needs to be run once in your code, typically as the host process is starting up, so it can hook a type resolver to the appdomain.

ErikJL replied on Friday, May 07, 2010

Thanks Rocky!

The workaround required a modification in my case. I kept getting a stack overflow when it tried to resolve an XML serialization assembly, so I modified the code to return a null value and that fixed the problem.

 

Assembly currDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            // get a list of all the assemblies loaded in our appdomain
            Assembly[] list = AppDomain.CurrentDomain.GetAssemblies();

            // search the list to find the assembly that was not found automatically
            // and return the assembly from the list

            foreach (Assembly asm in list)
                if (asm.FullName == args.Name)
                    return asm;

            // if the assembly wasn't already in the appdomain, then try to load it.
            //return Assembly.Load(args.Name); <-- stack overflow from an XML serialization assembly
            return null; <--- my modification
        }

JCardina replied on Tuesday, January 25, 2011

Erik you saved my life today with this post.  We had a release a couple of days ago and ran into the stack overflow after years of it not being a problem with the original code.  I was about to pull out my hair and then stumbled across this and it solved the problem.

Cheers!

Copyright (c) Marimer LLC