Background: Noda Time contains many serializable structs. While I dislike binary serialization, we received many requests to support it, back in the 1.x timeline. We support it
According to the MSDN, in .NET 4.0 basically you should not use ISerializable
for partially trusted code, and instead you should use ISafeSerializationData
Quoting from https://docs.microsoft.com/en-us/dotnet/standard/serialization/custom-serialization
Important
In versions previous to .NET Framework 4.0, serialization of custom user data in a partially trusted assembly was accomplished using the GetObjectData. Starting with version 4.0, that method is marked with the SecurityCriticalAttribute attribute which prevents execution in partially trusted assemblies. To work around this condition, implement the ISafeSerializationData interface.
So probably not what you wanted to hear if you need it, but I don't think there's any way around it while keeping using ISerializable
(other than going back to Level1
security, which you said you don't want to).
PS: the ISafeSerializationData
docs state that it is just for exceptions, but it doesn't seem all that specific, you may want to give it a shot... I basically can't test it with your sample code (other than removing ISerializable
works, but you knew that already)... you'll have to see if ISafeSerializationData
suits you enough.
PS2: the SecurityCritical
attribute doesn't work because it's ignored when the assembly is loaded in partial trust mode (on Level2 security). You can see it on your sample code, if you debug the target
variable in ExecuteUntrustedCode
right before invoking it, it'll have IsSecurityTransparent
to true
and IsSecurityCritical
to false
even if you mark the method with the SecurityCritical
attribute)