-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Binary formatter alternatives for resource serialisation #80155
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
For your specific case, assuming the properties are config equivalents (ie, |
I don't think that'll work unfortunately as the .resources files being serialised will be used by Al.exe to create satellite assemblies for 3rd-party customer apps, so we don't get to pick and choose the format the resources are serialised with. |
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsBinaryFormatter is obsolete and soon to be removed from. NET due to security concerns regarding serialisation of arbitrary data. Coupled with this are changes in recent .NET releases to the way .resources files should be serialised to disk with ResourceWriter. Resources of certain (non-primitive) types can no longer be serialised using ResourceWriter.AddResource as was possible in .NET Framework, and must be first serialised to byte arrays before being passed to PreserializedResourceWriter, but there is no suggestion as to what is the best method to serialise the resources into a byte array. This is a problem because I'm serialising properties of form controls like System.Drawing.Size into Therefore, I've been using BinaryFormatter to serialise objects to byte arrays before passing them PreserializedResourceWriter.AddBinaryaformattedResource. If BinaryFormatter is now obsolete, how are developers supposed to serialise their resources?
|
It's high time to make your own |
@GrabYourPitchforks, could you take a look at this as it seems related to binary serialization? |
TypeDescriptor.GetConverter(typeof(Size)).ConvertToInvariantString(size); and TypeDescriptor.GetConverter(typeof(Size)).ConvertFromInvariantString(size); Many .NET types have a |
The only way to do this safely is to have the resource reader and writer special-case specific types or data structures and to write them out using whatever format is appropriate for them. For example, if you're trying to serialize a If you're trying to serialize a Rect or a Size or a similar type, the writer would emit the appropriate marker followed by the data, and when the reader reads the marker, it goes down whatever specialized logic is needed to read the resource. Here's the crucial detail. If you want this to not have the same problems BinaryFormatter and related serializers have, you must follow one of the below patterns.
This is all a lot of work, when a much simpler solution exists today: Use string-based resources. If you need to smuggle custom types, then use JSON or XML or whatever mechanism is appropriate to turn your custom data object into a string. Then when you read the resource, read it back as a string, then JSON/XML/whatever-deserialize it back into the data structure you expect. |
Thanks for your detailed reply. The key point here is that our use case is creating satellite assemblies for third party applications supplied by customers, not our own applications. As such, we're not in a position to impose our own custom resource serialization protocols on third party applications. The customer would have to modify their app to perform this custom serialization in their own code, wouldn't they? The .NET runtime presumably expects resources in satellite assemblies to adhere to a proprietary Microsoft serialization format so a custom format will never work out of the box - I believe it's called MS-NRBF? I'm wondering if it's better for us to write a .ResX file instead of a .resources file, and pass that ResX to Al.exe? |
Just commenting here to see if there's been any update regarding BinaryFormatter and what to replace it with for WinForms resources? |
I'm coming across this issue in porting my .net framework application to .net8. Our software allows the compilation of C# during runtime via Microsoft.CodeAnalysis.CSharp.CSharpCompilation The following works on .net framework, but will throw an error when you feed it a .resx created by visual studio that contains icons,sizes,points etc on .net8 private static Stream ProvideResourceData(string resourceFullFilename)
{
// For non-.resx files just create a FileStream object to read the file as binary data
if (!resourceFullFilename.EndsWith(".resx", StringComparison.OrdinalIgnoreCase))
return new FileStream(resourceFullFilename, FileMode.Open);
// Remainder of this method converts a .resx file into .resource file data and returns it
// as a MemoryStream
MemoryStream shortLivedBackingStream = new MemoryStream();
using (ResourceWriter resourceWriter = new ResourceWriter(shortLivedBackingStream))
{
//resourceWriter.TypeNameConverter = TypeNameConverter;
using (ResXResourceReader resourceReader = new ResXResourceReader(resourceFullFilename))
{
resourceReader.BasePath = Path.GetDirectoryName(Path.GetFullPath(resourceFullFilename));
foreach (DictionaryEntry dictionaryEnumerator in resourceReader)
{
string resourceKey = dictionaryEnumerator.Key as string;
resourceWriter.AddResource(resourceKey, dictionaryEnumerator.Value);
}
}
// This needed because shortLivedBackingStream is now closed
return new MemoryStream(shortLivedBackingStream.GetBuffer());
} Using ericcdub's workaround
|
We incorporated WinForms resource scenarions in the BinaryFormatter removal during .NET 9. Here is the documentation related to the scenario: BinaryFormatter migration guide: WinForms apps. @mastahg @ericcdub -- Please let us know if this addresses your questions/issues. /cc @JeremyKuhne |
This issue has been marked |
This issue has been automatically marked |
BinaryFormatter is obsolete and soon to be removed from. NET due to security concerns regarding serialisation of arbitrary data. Coupled with this are changes in recent .NET releases to the way .resources files should be serialised to disk with ResourceWriter.
Resources of certain (non-primitive) types can no longer be serialised using ResourceWriter.AddResource as was possible in .NET Framework, and must be first serialised to byte arrays before being passed to PreserializedResourceWriter, but there is no suggestion as to what is the best method to serialise the resources into a byte array.
This is a problem because I'm serialising properties of form controls like System.Drawing.Size into
.resources files as part of creating satellite assemblies. These types don't implement their own serialisation to my knowledge.
Therefore, I've been using BinaryFormatter to serialise objects to byte arrays before passing them PreserializedResourceWriter.AddBinaryaformattedResource.
If BinaryFormatter is now obsolete, how are developers supposed to serialise their resources?
The text was updated successfully, but these errors were encountered: