Watson
Watson

Reputation: 1425

C# Keep [Serializable] attribute when publishing to nuget with Net Standard 2.0 library

I have a class library that has a class marked as [Serializable]. If I reference the project directly, I can serialize the class using BinaryFormatter:

 BinaryFormatter bf = new BinaryFormatter();
 MemoryStream ms = new MemoryStream();
 bf.Serialize(ms, obj);
 var data = ms.ToArray();

However, If I publish the class library through nuget, it loses the [Serializable] attribute and can no longer be converted to a byte array using the BinaryFormatter.

Is there a way to preserve the class AS-IS when you create the .nupkg? Currently, I'm just using Visual Studios Generate Nuget Package on build.

After further investigation let me clarify my findings.

*If you have a .net472 Web API and a .net472 class library and you publish the class library through nuget everything works. I have used BinaryFormatter to serialize an object that is marked with the [Serializable] attribute and send it to the server successfully and was able to deserialize it.

*If you have a .netstandard 2.0 library, and you publish it out to a .netstandard console project and attempt to serialize it with the binaryformatter you get the class is not marked as serializable (even though it's marked).

*If you have a .net472 library and you publish it out to a netstandard 2.0 console application, I was unable to serialize the class but it was for other reasons, in the case I had I received error:

Type 'System.Text.Encoding' in Assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' is not marked as serializable.'

In short, if you really need binary serialization, I don't know of any other option but for both the client and the server to support the full framework library and not a core/netstandard.

Upvotes: 2

Views: 708

Answers (1)

Kit
Kit

Reputation: 21729

Because .NET Standard does not define whether a type is serializable, I suspect that NuGet strips out the attribute on purpose when you target .NET Standard.

At best, it looks like NuGet is preserving the (ahem) standards of .NET Standard, but at worst, it's silently doing something you may not expect—stripping [Serializable].

So, with a bit of conjecture, it seems that the compiler doesn't care to strip the attribute or warn that it shouldn't be applied (possibly because in a multitargeting scenario, [Serializable] is allowed in some situations), but NuGet is being much more strict in your case because you're targeting only .NET Standard.

It seems like you can provide some runtime support to determine whether the type is serializable, but you can't do this at compile-time. Perhaps the only way to preserve the attribute is to target your library to .NET Core or .NET Framework.

Upvotes: 1

Related Questions