Open sebgrohn opened 3 years ago
Hi @sebgrohn, Thanks for reporting this issue. Yeah, that looks like a bug.
As another workaround, maybe try arrays instead of list?
Because, string[]
should work just fine, and technically, for serialization there isn't a difference between array and list anyways, performance wise or for your app.
Thanks for the suggestion, that's a good point!
I will admit that my example above was a bit simplified; what we have seen reported in exception logs is for example this:
System.Tuple<System.DateTime, {generic data collection type}<System.Collections.Generic.List<{DTO type}>>>
I'm afraid that we are caching similar types from other places in the code as well.
Here's the full workaround that we're adding to our shared code, if it is of any use for someone.
When testing it, we saw that it is only a problem when .NET Framework tries to read .NET Core-serialized values, not the other way around: Type.GetType
in .NET Core seem to have a built-in fallback for the "mscorlib" assembly name.
TypeCache.RegisterResolveType(typeName => {
const string NET_CORE_ASSEMBLY_NAME = "System.Private.CoreLib";
const string NET_FRAMEWORK_ASSEMBLY_NAME = "mscorlib";
// Try to get the type from the full qualified name.
var type = Type.GetType(typeName, false);
// Try remove version from the type string and resolve it (should work even for signed assemblies).
typeName = Regex.Replace(typeName, @", Version=\d+.\d+.\d+.\d+", string.Empty);
type ??= Type.GetType(typeName, false);
// Try replacing .NET Core's core-lib assembly name with corresponding
// .NET Framework name. This is needed because some caches are shared
// between .NET Core and .NET Framework
// projects, with differing assembly names for the standard system types.
type ??= Type.GetType(typeName.Replace(NET_CORE_ASSEMBLY_NAME, NET_FRAMEWORK_ASSEMBLY_NAME), false);
return type;
});
This will be improved with the next PR.
It's still not 100% going to work for all types because e.g. HashSet
Hi!
We have an issue with CacheManager and our Redis instance when reading and writing cached values from both ASP.NET Core and ASP.NET Framework. The two applications both read and write the same keys, and CacheManager sometimes can't find the correct type when deserializing values. When we started digging into what goes wrong we saw that we had some values serialized with .NET Core assembly name and some with the .NET Framework one: System.Private.CoreLib vs. mscorlib.
I found this code in
TypeCache.GetType
which, according to the comment, it's supposed to handle exactly this issue. And for simple type strings it works fine:is simplified to
System.Boolean
=> no problem to look up.On the other hand, for generic types such as
List<string>
, it doesn't work:is simplified to
System.Collections.Generic.List`1[[System.String
instead of the correctSystem.Collections.Generic.List`1[[System.String]]
=> look-up fails. Considering that you can nest generic types arbitrarily, this gives me a headache to think about. šµRight now I'm trying out workarounds via
RegisterResolveType
, such as this a bit hacky one:What are your thoughts about this? š