SVG icon indicating copy to clipboard operation
SVG copied to clipboard

Netstandard 2.0 - SvgDocument.GetXML()

Open HughGrovesArup opened this issue 4 years ago • 10 comments

I'm having trouble getting netstandard2.0 to work which was added in #509

The build command I am using (from the source directory) is:

dotnet build -c release -f netstandard2.0 Svg.csproj

I get the warning

warning NU1701: Package 'Fizzler 1.1.0' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.2'. This package may not be fully compatible with your project.

I noted that netstandard is only supported from v1.2 (rather than the v1.1 referenced on main). I blindly changed the version in the .csproj file and tried again (required removing the other compilation targets). This then build successfully.

I refernced this into my project and all seems well until I get to SvgDocument.GetXML() which throws the exception:

{System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeInitializationException: The type initializer for 'Svg.SvgElement' threw an exception. ---> System.PlatformNotSupportedException: System.Drawing is not supported on this platform.
   at System.Drawing.Text.PrivateFontCollection..ctor()
   at Svg.SvgElement..cctor() in C:\Users\Hugh.Groves\Documents\VS_Code_Projects\SVG-1\source\SvgElementStyle.cs:line 420
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
   at System.RuntimeFieldHandle.GetValue(RtFieldInfo field, Object instance, RuntimeType fieldType, RuntimeType declaringType, Boolean& domainInitialized)
   at System.Reflection.RtFieldInfo.UnsafeGetValue(Object obj)
   at System.Reflection.RtFieldInfo.GetValue(Object obj)
   at Svg.SvgElement.WriteAttributes(XmlTextWriter writer) in C:\Users\Hugh.Groves\Documents\VS_Code_Projects\SVG-1\source\SvgElement.cs:line 601
   at Svg.SvgFragment.WriteStartElement(XmlTextWriter writer) in C:\Users\Hugh.Groves\Documents\VS_Code_Projects\SVG-1\source\Document Structure\SvgFragment.cs:line 308
   at Svg.SvgElement.Write(XmlTextWriter writer) in C:\Users\Hugh.Groves\Documents\VS_Code_Projects\SVG-1\source\SvgElement.cs:line 788
   at Svg.SvgDocument.Write(XmlTextWriter writer) in C:\Users\Hugh.Groves\Documents\VS_Code_Projects\SVG-1\source\SvgDocument.cs:line 704
   at Svg.SvgDocument.Write(Stream stream, Boolean useBom) in C:\Users\Hugh.Groves\Documents\VS_Code_Projects\SVG-1\source\SvgDocument.cs:line 729
   at Svg.SvgExtentions.GetXML(SvgDocument doc) in C:\Users\Hugh.Groves\Documents\VS_Code_Projects\SVG-1\source\SvgExtentions.cs:line 38
   at DesignCheck2.Examples.DynamicImage.CreateImage(Double width, Double height) in c:\Users\Hugh.Groves\Documents\designcheck2\DesignCheck2\DesignCheck2\Examples\DynamicImage.cs:line 76
   at DesignCheck2.Examples.DynamicImage.<>c__DisplayClass0_0.<.ctor>b__0() in c:\Users\Hugh.Groves\Documents\designcheck2\DesignCheck2\DesignCheck2\Examples\DynamicImage.cs:line 35
   at DesignCheck2.Framework.ReportSvgGraphic_Delayed.get_SVG() in c:\Users\Hugh.Groves\Documents\designcheck2\DesignCheck2\DesignCheck2\Framework\Report.cs:line 424}

In my project I have referenced svg.dll and system.drawing.common.dll, what else am I doing wrong!

HughGrovesArup avatar Sep 20 '19 10:09 HughGrovesArup

@HughGrovesArup What is your Program target framework? I usually target multiple frameworks when publishing library so when its executed (usually net461 or netcoreapp2.2 target) the missing platform features are available in main app. I have custom nuget build https://www.nuget.org/packages/Svg.Custom that targets .NETStandard 2.0, .NETCoreApp 2.2 and .NETCoreApp 3.0.

wieslawsoltes avatar Sep 20 '19 10:09 wieslawsoltes

It's a plain netstandard2.0 class library. Just some simple functions being served over an API that we want the future flexibility to run on linux if required.

Thanks for the custom nuget builds, I'll give them a try.

HughGrovesArup avatar Sep 20 '19 11:09 HughGrovesArup

That's sorted things for me, thanks @wieslawsoltes!

HughGrovesArup avatar Sep 20 '19 11:09 HughGrovesArup

Actually spoke too soon, built and tested locally, but is failing on my VM with the error message

System.Drawing is not supported on this platform.

How can it be said to support netstandard2.0 if it requires a library (System.Drawing) that is not available? Would not all of the System.Drawing calls need to be replaced wih something that is available, or can be packaged in (I believe System.Drawing.Common?)

HughGrovesArup avatar Sep 20 '19 14:09 HughGrovesArup

Maybe its this issue: https://stackoverflow.com/questions/51904125/azure-function-gives-error-system-drawing-is-not-supported-on-this-platform

Did you try running using different target framework like net461 ?

wieslawsoltes avatar Sep 20 '19 19:09 wieslawsoltes

Actually spoke too soon, built and tested locally, but is failing on my VM with the error message

System.Drawing is not supported on this platform.

How can it be said to support netstandard2.0 if it requires a library (System.Drawing) that is not available? Would not all of the System.Drawing calls need to be replaced wih something that is available, or can be packaged in (I believe System.Drawing.Common?)

In the FAQ is some detail regarding the System.Drawing stuff. We need some Drawing and GDI stuff and that requires a wrapper/replacement on Linux and Mac systems. Also, some edgecases, like Azure functions simply do not support System.Drawing.

The .NET Standard defines that System.Drawing is part of the base system (https://docs.microsoft.com/en-us/dotnet/api/system.drawing?view=netstandard-2.0), but the implementors of each runtime environment are (as far as I know) free to limit/disable certain stuff. If you have a very limited installation (e.g. headless or whatever), there is a possibility some of the stuff is just not supported regardless of .NET standard.

gvheertum avatar Oct 01 '19 08:10 gvheertum

@HughGrovesArup I did some tinkering in the past with the SVG lib to get it in an API. I tried making a WebAPI (ASP.NET MVC) and Azure function. The azure function gave the same PlatformNotSupported exception, while the WebAPI was able to run just fine in a app service. I did not try to set the target to .NET standard, but I got it fully working with .NET Core. So it might be something you can check.

See: https://github.com/gvheertum/SvgToBitmapApi

gvheertum avatar Oct 01 '19 08:10 gvheertum

From my reading I had seen that System.Drawing.Common could be used instead of System.Drawing and then things would 'just work'. I had assumed that the inclusion of netstandard2.0 support would have made the switch from System.Drawing to System.Drawing.Common but it appears thats not the case.

If I get the chance I'll have a play and see if I can get it to work by using System.Drawing.Common

https://www.hanselman.com/blog/HowDoYouUseSystemDrawingInNETCore.aspx

(Appreciate the point about Azure functions not allowing it to work due to the GDI stuff).

HughGrovesArup avatar Oct 01 '19 08:10 HughGrovesArup

From my reading I had seen that System.Drawing.Common could be used instead of System.Drawing and then things would 'just work'. I had assumed that the inclusion of netstandard2.0 support would have made the switch from System.Drawing to System.Drawing.Common but it appears thats not the case.

If I get the chance I'll have a play and see if I can get it to work by using System.Drawing.Common

https://www.hanselman.com/blog/HowDoYouUseSystemDrawingInNETCore.aspx

Mmm, the article is a bit old. Since 2.0 the System.Drawing seems to be natively supported in standard (see also the Microsoft page, if you switch to standard < 2.0 you get a message that System.Drawing is not available, but in 2.0 it shows the namespace details), so I don't think there is an absolute need for a switch to common (correct me if I'm wrong). Also, the warning you get is something that should not be a problem (at least for me at MacOS no issues so far) since the framework is kinda able to do some "magic" to get it working. We are still investigating if we can have a standard/core version of the linked library to get rid of the warning.

By the way the gdiplus stuff is still needed on OS-es like Ubuntu (and I guess it also goes for MacOS) according to the article of Hanselman. Most stuff of the library even works without the GDI+ replacement and we did some changes to show a nice error when the GDI+ cannot be used. The error you get comes from a different place and really seems to be related to the implementation/capabilities of the deployment target (hence the different behavior locally and deployed). These exceptions even occur when deploying certain stuff to certain .Net 4.6+ targets (e.g. to run most PDF generators you need to move from App Services to Classic Cloud architecture on Azure since some of the lower level calls are just not enabled in AppServices.

We did come a long way since the article of Hanselman and the Standard supports a lot of stuff to be compiled against (the System.Drawing did not even compile in the past), but we are still dependent on the support of the target systems. This is a bit like how in the past UWP worked, there were a lot of calls that just no-opped or were not supported on some of the frameworks. .NET standard and core are a bit like that, they support compiling and coupling with a lot of calls, but not all calls might work on all platforms (e.g. in Core 3.0 you can build WPF and WinForms apps and technically you can start these compiled versions on MacOS, but unfortunately you will not be shown a GUI).

(Appreciate the point about Azure functions not allowing it to work due to the GDI stuff).

Funny thing is you can even see this behavior when running a function locally (at least if I remember correctly). The function will yield a platform not supported message, even when running on Windows, while the same code will work without problems outside of the function.

gvheertum avatar Oct 01 '19 09:10 gvheertum

This problem is definitely not solved. I just tried to use this in a .NET Standard 2.0 library from a UWP app, and I get the same unsupported exception. Why does it require System.Drawing to parse the file?

yoshiask avatar May 16 '20 07:05 yoshiask