I'm not sure, if this is a bug or just not implemented.
Having a class with a property of type "Type", once in a .Net framework and once in a UWP framework.
The type serializes with the AssemblyQualifiedName property of the type.
Thus serializing in the .Net framework rusults in something like
"System.EventArgs, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
If I deserialize this in an UWP application with JsonConver.DeserializeObject a propper Type object is created. Serializing this one in UWP, the following string is produced
"System.EventArgs, System.Private.CoreLib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = 7cec85d7bea7798e"
Trying to deserialize this back in a .Net framework application, I get the error
"Error converting value "System.EventArgs, System.Private.CoreLib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = 7cec85d7bea7798e" to type 'System.Type'."
The message is clear to me, but then I wouldn't expect why it works in the other direction. Is this due to tha fact, the UWP version is newer and can handle this convertion or is it a bug?
Serializing between different frameworks with the type name is unfortunately a very difficult problem. Just a quick look at https://apisof.net/catalog/System.EventArgs shows that System.EventArgs is defined in several different assemblies and even some of those are type-forwarded to private assemblies such as System.Private.CoreLib. The reason the UWP application can accept "System.EventArgs, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" is because there's an mscorlib facade assembly that type-forwards all of its types to the proper assemblies for UWP.
I'm really not sure what solution there can be for this. Perhaps a library could be created to map the various system type names to it's proper type for the runtime framework and the SerializationBinder could reference that library.
Implement your own ISerializationBinder. With it you can customize the generatation and handling of the type name.
For large code-base that vannot be easily converted to a custom ISerializationBinder
I have implement a redirect (not pretty but it works)
RedirectAssembly("System.Private.CoreLib", "mscorlib");
public static void RedirectAssembly(string fromAssemblyShotName, string replacmentAssemblyShortName)
{
Console.WriteLine($"Adding custom resolver redirect rule form:{fromAssemblyShotName}, to:{replacmentAssemblyShortName}");
ResolveEventHandler handler = null;
handler = (sender, args) =>
{
// Use latest strong name & version when trying to load SDK assemblies
var requestedAssembly = new AssemblyName(args.Name);
Console.WriteLine($"RedirectAssembly > requesting:{requestedAssembly}; replacment from:{fromAssemblyShotName}, to:{replacmentAssemblyShortName}");
if (requestedAssembly.Name == fromAssemblyShotName)
{
try
{
Console.WriteLine($"Redirecting Assembly {fromAssemblyShotName} to: {replacmentAssemblyShortName}");
var replacmentAssembly = Assembly.Load(replacmentAssemblyShortName);
return replacmentAssembly;
}
catch (Exception e)
{
Console.WriteLine($"ERROR while trying to provide replacement Assembly {fromAssemblyShotName} to: {replacmentAssemblyShortName}");
Console.WriteLine(e);
return null;
}
}
Console.WriteLine($"Framework faild to find {requestedAssembly}, trying to provide replacment from:{fromAssemblyShotName}, to:{replacmentAssemblyShortName}");
return null;
};
AppDomain.CurrentDomain.AssemblyResolve += handler;
}
Most helpful comment
For large code-base that vannot be easily converted to a custom ISerializationBinder
I have implement a redirect (not pretty but it works)