-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NativeAOT and XmlSerializer #106580
Comments
It would be amazing if XML serialization could get the same treatment as JSON and have a source-generated AOT-safe {de}serializer. Such a thing would be a large undertaking, and although I think it would be worth it (a shocking amount of people and enterprises use XML and have no plans on transitioning away), I can understand any hesitancy in committing to that kind of project. |
We were facing the same issue, and I had some short discussion with people on the .NET team. There's no immediate solution right now, and in the end we ended up rewriting most of our code to manually implement |
The thing is, there's already a code for the source generation (SGen) but there's no way to integrate it into NativeAOT executable easily. The traditional SGen (available on modern .NET as NuGet) generates an additional assembly and the SGen uses reflection to load the original assembly and to form an object model for the XML schema. It then uses the XML schema model to source generate the code. Unfortunately, the reflection code is quite old and depends on the runtime loading of the assembly. It's not possible to simply migrate it to work on top of I had the idea to use a modified Roslyn.Reflection to create a source generator that would simply reuse most of the existing infrastructure for source generation. The problem turned out to be that lot of the schema reading code depends on the types existing in the same runtime context, much like the issue with (Now, if you start from an XML schema in the first place, you can write a code that load it, runs the same SGen internal code to produce the source code, and you will be 90% there with "nice" C# code. It still doesn't fix everything since the source generated code still relies on some reflection logic that doesn't quite work in NativeAOT scenarios, but that would be fixable.) |
After some back and forth with @Suchiman here's a minimal sample of using SGen in NativeAOT: https://gist.github.com/filipnavara/1e8831c256498bad53b3aae94af87a20 There are few things that were done there:
Presumably, |
Thanks for your comments, @filipnavara. I took your gist, and ran with it. I have a fix, and can generate the serialization code (for my assembly), but:
Stay tuned. |
Also running into this issue, unfortuantely looks like AOT will not be possible for our usecase until some sort of support comes along for XmlSerialization. Praying for that JSON treatment and a proper source generator 🤞 |
Same issue on NET 8 and NET 9 RC 1. But AOT can deal with simple XML files. But i got dead end error with XmlArray on List public fields public class ClassName
{
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ClassName))]
public ClassName() { }
[XmlArray("ItemsName")]
[XmlArrayItem("ItemName")]
public List<ItemType> Item { get; init; }
}
|
That exception is being raised from here
If i read the code correctly, it's trying to find the indexer on the List<ItemType> (that is list[42] = ... ) but its probably trimmed away or omitted from reflection info.Try adding typeof(List<ItemType>).GetDefaultMembers(); somewhere in your code that is guaranteed to execute.That should hint NAOT sufficiently to make sure to include that information. |
Yes. It works, thank you @Suchiman. I have large and complex xml with few levels of nesting. Good way to hint NAOT what types are using in model is adding Pseudo-code for clarification what i mean. You should recheck it if you suppose to use it but main conception saved: <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Root>
<ChildNode/>
<AnotherChildNodes>
<AnotherChildNode/>
<AnotherChildNode/>
<AnotherChildNode/>
<AnotherChildNode/>
</AnotherChildNodes>
</Root> // this code won't work in NativeAot
[XmlRoot]
public class Root {
public ChildNodeType ChildNode {get;set;}
[XmlArray("AnotherChildNodes")]
[XmlArrayItem("AnotherChildNode")]
public List<AnotherChildNodeType> AnotherChildNodes {get;set;}
}
public class AnotherChildNodeType {
// fields
}
public class ChildNodeType {
// fields
} // this code will
[XmlRoot]
public class Root {
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Root))]
public Root() {
typeof(List<AnotherChildNodeType>).GetDefaultMembers();
typeof(AnotherChildNodeType).GetDefaultMembers();
typeof(ChildNodeType).GetDefaultMembers();
}
public ChildNodeType ChildNode {get;set;}
[XmlArray("AnotherChildNodes")]
[XmlArrayItem("AnotherChildNode")]
public List<AnotherChildNodeType> AnotherChildNodes {get;set;}
}
public class AnotherChildNodeType {
public AnotherChildNodeType() {
// typeof(FieldOfClass).GetDefaultMembers(); ...
}
// fields
}
public class ChildNodeType {
public ChildNodeType() {
// typeof(FieldOfClass).GetDefaultMembers(); ...
}
// fields
} |
Description
When publishing a test application which uses XML serialization, vi code generated via
xscgen
(see here) along withPublishAot
, the application crashes because the serialization code relies heavily upon reflection.The stack trace is, then:
However, I have (in the real application) also seen the following stack:
The test project, which I have tried to prune as much as possible, can be found here: XmlSerializationTest.zip
xscgen
, and what attributes are finally used to mark the generated classes and fields, andSystem.Collections.ObjectModel.Collection`1
)System.Private.Xml
be modified (to support this scenario)?TrimmerSingleWarn
is true), or are other warnings/issues (perhaps being masked)?src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs
: 25 hitssrc/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs
: 1 hitsrc/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs
: 6 hitssrc/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs
: 1 hitsrc/libraries/System.Private.Xml/src/System/Xml/Serialization/NameTable.cs
: 1 hitReproduction Steps
Compile and run attached project:
Expected behavior
The test program should successfully serialize and deserialize a basic data structure to and from XML.
Actual behavior
See stack trace of crash in the description.
Regression?
No.
Known Workarounds
No response
Configuration
Other information
See also this issue in
xscgen
The text was updated successfully, but these errors were encountered: