winforms icon indicating copy to clipboard operation
winforms copied to clipboard

NET8: BinaryFormatter not supported when .resx contains "application/x-microsoft.net.object.binary.base64"

Open panxn opened this issue 2 years ago • 16 comments

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

panxn avatar Jul 14 '23 07:07 panxn

Linking related issues: https://github.com/dotnet/runtime/issues/88217, https://github.com/dotnet/runtime/issues/88316

GrabYourPitchforks avatar Jul 29 '23 18:07 GrabYourPitchforks

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:

area-System.Runtime, untriaged

Milestone: -

ghost avatar Aug 03 '23 21:08 ghost

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:

area-System.Resources, untriaged

Milestone: -

ghost avatar Aug 07 '23 20:08 ghost

@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?

ericstj avatar Aug 07 '23 22:08 ericstj

@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 avatar Aug 08 '23 00:08 JeremyKuhne

@JeremyKuhne I tried following steps to add application/x-microsoft.net.object.binary.base64 into .resx successfully:

  1. create winform project in VS
  2. double click "Form1.cs" to enter designer
  3. View->Toolbox, drag "ImageList" to main panel
  4. 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 avatar Aug 09 '23 10:08 panxn

@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 avatar Aug 09 '23 20:08 JeremyKuhne

@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.

panxn avatar Aug 10 '23 04:08 panxn

@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.

paul1956 avatar Aug 10 '23 06:08 paul1956

The original issue was 9174.

Repro steps:

  1. Create winform .NET 8.0 Core project
  2. Change the TargetFramework from net8.0-windows to net9.0-windows in the csproj file
  3. Add an ImageList control to form designer
  4. Open smarttag and add some images
  5. Build and run

Actual result: Exception pops up when executing ImageList.ImageCollection.SetKeyName(Int32 index, String name) imagelist

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

MelonWang1 avatar Oct 25 '23 07:10 MelonWang1

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 image

Amy-Li03 avatar Nov 09 '23 07:11 Amy-Li03

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 avatar Dec 01 '23 15:12 AngeloCresta

@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

MelonWang1 avatar Dec 04 '23 07:12 MelonWang1

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.

damien-c-d avatar May 15 '24 05:05 damien-c-d

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.

image

Liv-Goh avatar Jun 28 '24 08:06 Liv-Goh

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

AngeloCresta avatar Jun 28 '24 12:06 AngeloCresta

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.

noname-1234-ai avatar Jul 11 '24 07:07 noname-1234-ai

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.

canislupus-llc avatar Jul 15 '24 21:07 canislupus-llc

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.

JeremyKuhne avatar Jul 24 '24 22:07 JeremyKuhne

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

Philip-Wang01 avatar Aug 29 '24 09:08 Philip-Wang01