Reputation: 79
I have migrated a couple of ASP.Net Core 2.2 projects to .Net 5, the last issue I have is that I get a System.NotSupported exception when trying to load bitmaps from the project resources.
RtfUtility.AppendLogo(result, Properties.Resources.Logo);
System.NotSupportedException HResult=0x80131515 Message=BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information. Source=System.Runtime.Serialization.Formatters
I'm not using BinaryFormatter explicitly but oddly I don't get an error when loading a binary PDF file in the same way:
processor.LoadDocument(new MemoryStream(Properties.Resources.Certificate));
Both mechanisms use ResourceManager.GetObject, so I'm not sure whats going on. I know I can turn off the error in the project file, but that seems to be a short term solution, I'd rather fix it and forget it. Thanks for any advice you can give...
Edit:
Stack Trace is below, The error is not caused by the library, it is when accessing the resource. It happens when the image is embedded or linked - seems to make no difference, but doesn't happen with a (binary) PDF file.
Thanks for looking at this...
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream) at System.Resources.ResourceReader.<>c__DisplayClass7_0`1.b__0(Object obj, Stream stream) at System.Resources.ResourceReader.DeserializeObject(Int32 typeIndex) at System.Resources.ResourceReader._LoadObjectV2(Int32 pos, ResourceTypeCode& typeCode) at System.Resources.ResourceReader.LoadObjectV2(Int32 pos, ResourceTypeCode& typeCode) at System.Resources.ResourceReader.LoadObject(Int32 pos, ResourceTypeCode& typeCode) at System.Resources.RuntimeResourceSet.GetObject(String key, Boolean ignoreCase, Boolean isString) at System.Resources.RuntimeResourceSet.GetObject(String key, Boolean ignoreCase) at System.Resources.ResourceManager.GetObject(String name, CultureInfo culture, Boolean wrapUnmanagedMemStream) at System.Resources.ResourceManager.GetObject(String name, CultureInfo culture) at Project.Infrastructure.Properties.Resources.get_Logo() in C:\Development\Project\Project.Infrastructure\Properties\Resources.Designer.cs:line 227 at Project.Infrastructure.Models.ShowWording.Generate() in C:\Development\Project\Project.Infrastructure\Models\ShowWording.cs:line 146
Upvotes: 6
Views: 26198
Reputation: 18023
Microsoft is getting rid of BinaryFormatter
, which is totally understandable.
it is odd that I get the BinaryFormatter exception when reading an image, but not a Binary file
A binary file is not serialized by BinaryFormatter
but saved as a simple byte array or added as a special resource that can be accessed as a memory stream. Actually you can make images to be accessible as streams in the resource files pretty easily (the linked answer focuses for WPF compatibility for the image resources but the first part still applies).
In case you still need to read old resource files in .NET Core/.NET that contain BinaryFormatter
resources you can use my own resource handling libraries that can work directly on .resx files (GitHub), which ironically provides better backward compatibility with legacy resource files than .NET Core/.NET itself. It also supports saving resources in legacy format. But please note that when targeting .NET 8 or later, BinaryFormatter
compatibility will not work anymore even by this library. (Update for clarification: if you don't force compatible .resx format on saving, you will able to use such custom resources even in .NET 8+ but in that case my alternative binary serializer will be used under the hood. See the Safety section of the ResXResourceManager
class for details)
Upvotes: 2
Reputation: 1
Add the following property group to your .csproj file:
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<!-- Warning: Setting the following switch is *NOT* recommended in web apps. -->
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
Upvotes: 7
Reputation: 6383
It seems that Visual Studio/.Net previously made images added as resources accessible as Image
, which makes use of the BinaryFormatter
, while if I now add images they are accessible as byte[]
.
I was able to update the resource file to only return byte[]
by simply:
System.Drawing.Bitmap
with byte[]
in the *.Designer.cs fileSystem.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
with System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
in the *.resx filePreviously :
// In the *.Designer.cs file
public static System.Drawing.Bitmap MyImage {
get {
object obj = ResourceManager.GetObject("MyImage", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
// In the *.resx file
<data name="MyImage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Path\To\MyImage.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
Now:
// In the *.Designer.cs file
public static byte[] MyImage {
get {
object obj = ResourceManager.GetObject("MyImage", resourceCulture);
return ((byte[])(obj));
}
}
// In the *.resx file
<data name="MyImage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Path\To\MyImage.jpg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></value>
</data>
Upvotes: 1
Reputation: 79
I found a workaround, that doesn't make sense, but I trust it more than allowing unsafe Binary Formatters in my projects.
Following on from your suggestions I tried deleting and recreating the resource file, removing and re-adding the affected image, but nothing worked.
So, because reading a pdf file worked, I removed the .png extension from my image and saved it as a File resource.
I can now read it from resources as binary and convert it to Bitmap and it works fine.
using (var ms = new MemoryStream(Properties.Resources.LogoBinary))
{
return new Bitmap(ms);
}
I can't believe this is a bug in the framework, as it would affect a lot of people, it must be something peculiar to my project, but it is odd that I get the BinaryFormatter exception when reading an image, but not a Binary file...
Thanks everyone for your guidance & assistance...
Upvotes: 0
Reputation: 36629
BinaryFormatter serialization methods are obsolete and prohibited in ASP.NET apps. However, the article does not say anything about the resourceReader or other classes, even if the same security warning applies.
So I would presume that this is a bug. At a minimum I would have expected the documentation to explicitly state that binary resources are not supported, or any other compatibility constraints. I would consider creating a minimal reproducible example to ensure there is no other weird build issue causing the problem, and posting a bug report about it.
Note that there seem to be various issues reported about binary resources in .net core, but it is unclear to me what the final resolution is.
As a workaround there is an option to re enable binaryformatter in .Net 5 asp.Net apps by adding the following to the project file.
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<!-- Warning: Setting the following switch is *NOT* recommended in web apps. -->
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
Upvotes: 15