1

Closed

DefaultSerializationBinder.GetTypeNameFromTypeKey() : Check loaded assemblies before calling LoadWithPartialName()

description

Greetings and thanks for this fantastic library.

My issue is this:

When I attempt to deserialize an object that was serialized with types from assemblies that were loaded from outside of the GAC and EXE directories, it fails because it cannot find the assembly in either place when calling Assembly.LoadWithPartialName().

If, however, the list of loaded assemblies is checked with AppDomain.CurrentDomain.GetAssemblies() for a matching assemblyname, this assembly can be used without a call to LoadWithPartialName.

I was able to make this change to the source to solve this issue, but perhaps there is a more elegant solution that doesn't involve source modification, or this feature could be added without much impact?

file attachments

Closed May 2, 2013 at 10:00 AM by JamesNK
Done

comments

JamesNK wrote Apr 17, 2013 at 12:21 PM

Could you attach your source code and an example of the problem it solves?

Millsington wrote Apr 20, 2013 at 12:09 AM

Turns out 4.5.10.15407 does not have this problem so that is probably a better place to look into what changed to cause this issue.

Here's a Visual Studio solution that demonstrates the problem. Just change the path at the top of the startup form to point to the DLL output of the ClassLibrary2 project.

Millsington wrote Apr 20, 2013 at 1:52 AM

Very sorry, for some reason the assembly version was being misreported in the add reference dialog, 4.5 does still have this issue.

My solution was this (in DefaultSerializationBinder.cs):
    private static Type GetTypeFromTypeNameKey(TypeNameKey typeNameKey)
    {
      string assemblyName = typeNameKey.AssemblyName;
      string typeName = typeNameKey.TypeName;

      if (assemblyName != null)
      {
        Assembly assembly = null;

        var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
        foreach (var assy in loadedAssemblies)
        {
            if (assy.FullName == assemblyName)
                assembly = assy;
        }

#if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE)
        // look, I don't like using obsolete methods as much as you do but this is the only way
        // Assembly.Load won't check the GAC for a partial name
#pragma warning disable 618,612        
        if (assembly == null)
            assembly = Assembly.LoadWithPartialName(assemblyName);
#pragma warning restore 618,612
Pure hack, I know.