NET8: BinaryFormatter not supported when .resx contains "application/x-microsoft.net.object.binary.base64"
Description
I'm using .NET8, our .resx files contains <data name="imageList1.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
They can be successfully built but throw exception at runtime.
BinaryFormatter serialization and deserialization are disabled within this application.
I know BinaryFormatter is going to be deprecated, and I can re-enable it by EnableUnsafeBinaryFormatterSerialization=true, but it's just a temporary solution.
Will dotnet team enhance the build tool to support these .resx files? or we developers should update .resx files? and what is the recommended way?
BTW, is there some help document for developers to adapt to the obsolescence of BinaryFormatter? For example, how to read existing files saved by BinaryFormatter, how to deal with application/x-microsoft.net.object.binary.base64 in .resx. I believe it will be very helpful.
Reproduction Steps
No
Expected behavior
If mimetype="application/x-microsoft.net.object.binary.base64" can be built, it should not throw.
Actual behavior
It throws exception.
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response
Linking related issues: https://github.com/dotnet/runtime/issues/88217, https://github.com/dotnet/runtime/issues/88316
Tagging subscribers to this area: @dotnet/area-system-runtime See info in area-owners.md if you want to be subscribed.
Issue Details
Description
I'm using .NET8, our .resx files contains <data name="imageList1.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
They can be successfully built but throw exception at runtime.
BinaryFormatter serialization and deserialization are disabled within this application.
I know BinaryFormatter is going to be deprecated, and I can re-enable it by EnableUnsafeBinaryFormatterSerialization=true, but it's just a temporary solution.
Will dotnet team enhance the build tool to support these .resx files? or we developers should update .resx files? and what is the recommended way?
BTW, is there some help document for developers to adapt to the obsolescence of BinaryFormatter? For example, how to read existing files saved by BinaryFormatter, how to deal with application/x-microsoft.net.object.binary.base64 in .resx. I believe it will be very helpful.
Reproduction Steps
No
Expected behavior
If mimetype="application/x-microsoft.net.object.binary.base64" can be built, it should not throw.
Actual behavior
It throws exception.
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response
| Author: | panxn |
|---|---|
| Assignees: | - |
| Labels: |
|
| Milestone: | - |
Tagging subscribers to this area: @dotnet/area-system-resources See info in area-owners.md if you want to be subscribed.
Issue Details
Description
I'm using .NET8, our .resx files contains <data name="imageList1.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
They can be successfully built but throw exception at runtime.
BinaryFormatter serialization and deserialization are disabled within this application.
I know BinaryFormatter is going to be deprecated, and I can re-enable it by EnableUnsafeBinaryFormatterSerialization=true, but it's just a temporary solution.
Will dotnet team enhance the build tool to support these .resx files? or we developers should update .resx files? and what is the recommended way?
BTW, is there some help document for developers to adapt to the obsolescence of BinaryFormatter? For example, how to read existing files saved by BinaryFormatter, how to deal with application/x-microsoft.net.object.binary.base64 in .resx. I believe it will be very helpful.
Reproduction Steps
No
Expected behavior
If mimetype="application/x-microsoft.net.object.binary.base64" can be built, it should not throw.
Actual behavior
It throws exception.
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response
| Author: | panxn |
|---|---|
| Assignees: | - |
| Labels: |
|
| Milestone: | - |
@dotnet/dotnet-winforms and @dotnet/project-system for additional help here. I believe they are working on things that can help you.
In the case of imageList1.ImageStream this is an https://github.com/dotnet/winforms/blob/bb80c8dcb9df853e116d4eaba442c86b62273f72/src/System.Windows.Forms/src/System/Windows/Forms/ImageListStreamer.cs @lonitra @JeremyKuhne - how should folks move to a non-binary formatted version of this type?
@lonitra @JeremyKuhne - how should folks move to a non-binary formatted version of this type?
@panxn The more explicit the details of your scenario the better we'll be able to help you. How are you getting these into your resx and consuming them? Is this just from using the WinForms designer?
In .NET 8 if you use ResxResourceReader/Writer directly it will work with some .NET binary formatted types without the BinaryFormatter enabled. We're planning on handling the WinForms types that need the BinaryFormatter, but that probably won't be complete until .NET 9.
If you need or want to continue using resx, the general recommendation is to create type converters for all of your own types that you wish to serialize and apply them to types via the [TypeConverter] attribute. Type converters that round trip with string or byte[] are always preferred over BinaryFormatter.
@JeremyKuhne I tried following steps to add application/x-microsoft.net.object.binary.base64 into .resx successfully:
- create winform project in VS
- double click "Form1.cs" to enter designer
- View->Toolbox, drag "ImageList" to main panel
- in "Properties" palette, click "Choose images", add images and save
Perhaps ResXResourceWriter is another way, I didn't try it.
I can workaround this problem by setting EnableUnsafeBinaryFormatterSerialization=true. However, I know this way is not available is .NET9. so I created this issue to look for a long-term solution.
@panxn Thanks for the additional information! We're planning to figure out a solution for the WinForms designer for .NET 9 for core WinForms types (which this is one). We'll also be looking at giving guidance in the designer when BinaryFormatter scenarios come up. As your particular scenario is with the WinForms designer, I'm going to move this to our repository.
WinForms and WPF projects should have the BinaryFormatter enabled by default for .NET 8. If this isn't happening for your project we can investigate with @GrabYourPitchforks.
@JeremyKuhne thank you!
As for this question:
WinForms and WPF projects should have the enabled by default for .NET 8. If this isn't happening for your project we can investigate with @GrabYourPitchforks.
BinaryFormatter
I think it's because the main frame of our product is MFC, the entry assembly of .NET is a c++/cli module, winform&wpf are used in other C# modules.
I tried in .NET8, the runtimeconfig.json for the c++/cli module sets EnableUnsafeBinaryFormatterSerialization to false even though it has <FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" /> in vcxproj. However, it's not a problem for us, we can set EnableUnsafeBinaryFormatterSerialization to true in vcxproj.
@JeremyKuhne, I get 99 Binary Formatter Warnings when I open my project if I try to use .Net 8. Even with .Net 7 and no errors there are still issues with latest release and prerelease with Designer does not allow any changes without corrupting the .Designer file and crashing. One specific type causing the issue is KeyValuePair(of String, KnownColor) gets converted to KeyValuePair. But there may be others. All of this has been reported with feedback tool and a project that shows the issues is on GitHub ( could do a smaller one if required).
How am I supposed to replace BinaryConverter when I don't use it the designer does. Will there be a 1-time upgrade to convert existing Designer File to not use BinaryFormatter but something else?
If I want to try .Net8 where is the procedure to correctly do it with WinForms. If EnableUnsafeBinaryFormatterSerialization is required for WinForms why is that not automatically set.
The original issue was 9174.
Repro steps:
- Create winform .NET 8.0 Core project
- Change the TargetFramework from net8.0-windows to net9.0-windows in the csproj file
- Add an ImageList control to form designer
- Open smarttag and add some images
- Build and run
Actual result:
Exception pops up when executing ImageList.ImageCollection.SetKeyName(Int32 index, String name)
Call Stack: System.IndexOutOfRangeException HResult=0x80131508 Message=Index was outside the bounds of the array. Source=System.Windows.Forms StackTrace: at System.Windows.Forms.ImageList.ImageCollection.SetKeyName(Int32 index, String name) at WinFormsApp119.Form1.InitializeComponent() in C:\Users\xxxg\source\repos\WinFormsApp119\WinFormsApp119\Form1.Designer.cs:line 40 at WinFormsApp119.Form1..ctor() in C:\Users\xxx\source\repos\WinFormsApp119\WinFormsApp119\Form1.cs:line 7 at WinFormsApp119.Program.Main() in C:\Users\xxx\source\repos\WinFormsApp119\WinFormsApp119\Program.cs:line 14
Failed to load 'Explorer Form' template forms designer on a winforms .NET VB project when targeting .NET 9.0.
It has also appeared on a targeting .NET 8.0 projects before. https://github.com/microsoft/winforms-designer/issues/5233
MelonWang1 - Amy-Li03 have you already tried to add:
<PropertyGroup> <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage> <EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization> <NoWarn>$(NoWarn);SYSLIB0011</NoWarn> <GenerateResourceWarnOnBinaryFormatterUse>false</GenerateResourceWarnOnBinaryFormatterUse> </PropertyGroup>
to the .net9 project file? Just to test other behavior of the project avoiding the "well known" issue on binary formatter ...
@AngeloCresta Verified this in .NET 9.0.100-alpha.1.23580.4, issues https://github.com/dotnet/winforms/issues/9174 and https://github.com/microsoft/winforms-designer/issues/5233 were fixed when add above codes in .csproj file.
https://github.com/dotnet/winforms/assets/94418985/d4a280dd-4d41-4bce-bfef-fdf3a177a639
I'm getting a warning for this in .NET 8. Has there been any progress so far? Or is it just going to break when we upgrade to .NET 9? It's disappointing something still hasn't been done about it but I just hope there's a solution by the first RC for .NET 9.
Verified this in .NET 9.0.100-preview.7.24323.5, the binary formatter issue on image list unable to fix by adding codes above to the .csproj file.
Yes, in version .NET 9.0.100-preview.7.24323.5 the image file is not serialized and added to the .resx file (you can check) and the designer part is "missing" the image stream source:
imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
It's by design ... and they're not ready to replace the BinaryFormatter in winforms for builtin components like ImageList (not working) Angelo
mimetype: application/x-microsoft.net.object.binary.base64 value : The object must be serialized with : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 value : The object must be serialized with : System.Runtime.Serialization.Formatters.Soap.SoapFormatter : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 value : The object must be serialized into a byte array : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding.
I was able to work around this issue by removing the ImageList from the form designer altogether, and instead initializing one at runtime from images that I saved as project resources.
In other words, when initializing the form, just build an ImageList from image resources, then assign it as the ImageList for the control (in my case, a TreeView).
This worked fine, and the warning disappeared.
We've enabled embedded binary format resources in the .NET Runtime repo. @Tanya-Solyanik and @Shyam-Gupta are investigating workflow scenarios in the designer around generating the embedded resources.
Verified this with the latest internal VS: 17.12.0 Preview 2.0 + .NET SDK 9.0.100-rc.2.24428.6 build, it was fixed. BinaryFormatter support when .resx contains "application/x-microsoft.net.object.binary.base64"
https://github.com/user-attachments/assets/9676348e-6b5d-4d60-837d-f6f49766a900