Statically generated XML parsing code using `Microsoft.XmlSerializer.Generator` and `sgen` is not called breaking AOT compatibility

3 weeks ago 27
ARTICLE AD BOX

I am converting a .NET 9 project to .NET 10 and making it AOT compatible.

One of the things I need to do is make XML parsing AOT compatible, and I am using Microsoft.XmlSerializer.Generator to create native XML parsing code.

I get the project part working, and I can see the generated serialization code, but when I run my code the pre-generated serialization code is not used, and I still get compiler warnings that my code is not AOT compatible.

As far as I researched the XML factory should automatically pick up on the generated code and use it, but putting breakpoints in that code is not hit.

As example:

I create C# code from XSD using xsd D:\mediainfo_2_0.xsd /classes /namespace:Sandbox with mediainfo_2_0.xsd.

I do not want sgen on all classes, and I add

<SGenTypes>Sandbox.TestXml;Sandbox.mediainfoType;Sandbox.creationType;Sandbox.extraType;Sandbox.trackType;Sandbox.mediaType</SGenTypes>

to the .csproj file.

When I compile I see that code is generated .NET Xml Serialization Generation Utility, Version 10.0.1] Importing mediainfoType (2/6).

In my code I still get dotnet format errors about AOT, IL2026 and IL3050.

If I put a breakpoint on the generated factory code, it never gets hit:

public override System.Xml.Serialization.XmlSerializer GetSerializer(System.Type type)

Creating C# code from XSD, and creating XML file to deserialize:

xsd D:\mediainfo_2_0.xsd /classes /namespace:Sandbox mediainfo 'D:\test\foo.mkv' --Output=XML > D:\MediaInfo.xml

.csproj file:

<ItemGroup> <PackageReference Include="Microsoft.XmlSerializer.Generator" Version="10.0.1" /> </ItemGroup> <PropertyGroup> <SGenVerbose>true</SGenVerbose> <SGenTypes>Sandbox.TestXml;Sandbox.mediainfoType;Sandbox.creationType;Sandbox.extraType;Sandbox.trackType;Sandbox.mediaType</SGenTypes> </PropertyGroup>

Code example:

XmlSerializer serializer = new XmlSerializer(typeof(mediainfoType)); using FileStream fsXml = new(@"D:\MediaInfo.xml", FileMode.Open); using XmlReader reader = XmlReader.Create( fsXml, new XmlReaderSettings { DtdProcessing = DtdProcessing.Prohibit, XmlResolver = null } ); mediainfoType mediaInfo = (mediainfoType)serializer.Deserialize(reader);

dotnet format errors:

C:\Users\piete\Source\Repos\ptr727\PlexCleaner\Sandbox\TestSomething.cs(14,36): info IL2026: Using member 'System.Xml.Serialization.XmlSerializer.XmlSerializer(Type)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Members from serialized types may be trimmed if not referenced directly. [C:\Users\piete\Source\Repos\ptr727\PlexCleaner\Sandbox\Sandbox.csproj] C:\Users\piete\Source\Repos\ptr727\PlexCleaner\Sandbox\TestSomething.cs(14,36): info IL3050: Using member 'System.Xml.Serialization.XmlSerializer.XmlSerializer(Type)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. XML serializer relies on dynamic code generation which is not available with Ahead of Time compilation. [C:\Users\piete\Source\Repos\ptr727\PlexCleaner\Sandbox\Sandbox.csproj] C:\Users\piete\Source\Repos\ptr727\PlexCleaner\Sandbox\TestSomething.cs(17,50): info IL2026: Using member 'System.Xml.Serialization.XmlSerializer.Deserialize(Stream)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Members from deserialized types may be trimmed if not referenced directly. [C:\Users\piete\Source\Repos\ptr727\PlexCleaner\Sandbox\Sandbox.csproj] C:\Users\piete\Source\Repos\ptr727\PlexCleaner\Sandbox\TestSomething.cs(17,50): info IL3050: Using member 'System.Xml.Serialization.XmlSerializer.Deserialize(Stream)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. XML serializer relies on dynamic code generation which is not available with Ahead of Time compilation. [C:\Users\piete\Source\Repos\ptr727\PlexCleaner\Sandbox\Sandbox.csproj]

Generated code:

public override System.Xml.Serialization.XmlSerializer GetSerializer(System.Type type) { if (type == typeof(global::Sandbox.TestXml)) return new TestXmlSerializer(); if (type == typeof(global::Sandbox.mediainfoType)) return new mediainfoTypeSerializer(); if (type == typeof(global::Sandbox.creationType)) return new creationTypeSerializer(); if (type == typeof(global::Sandbox.extraType)) return new extraTypeSerializer(); if (type == typeof(global::Sandbox.trackType)) return new trackTypeSerializer(); if (type == typeof(global::Sandbox.mediaType)) return new mediaTypeSerializer(); return null; }

I have successfully converted my JSON parsing to use JsonSerializerContext which works great, but I cannot get my XML parsing to be AOT compatible.

Any help appreciated

Read Entire Article