Skip to content
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

XmlSerializer.Serialize doesn't work when using TrimMode=link #44772

Merged
merged 3 commits into from
Dec 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.XmlAttributes.get_IgnoreAttribute</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2057</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.XmlSerializationWriterCodeGen.WriteCheckDefault(System.Xml.Serialization.TypeMapping,System.String,System.Object,System.Boolean)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2057</argument>
Expand All @@ -41,13 +47,25 @@
<argument>ILLink</argument>
<argument>IL2067</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.CodeGenerator.CreateTypeBuilder(System.Reflection.Emit.ModuleBuilder,System.String,System.Reflection.TypeAttributes,System.Type,System.Type[])</property>
<property name="Target">M:System.Xml.Serialization.ReflectionXmlSerializationReader.ReflectionCreateObject(System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2067</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.ReflectionXmlSerializationReader.ReflectionCreateObject(System.Type)</property>
<property name="Target">M:System.Xml.Serialization.Compiler.AddImport(System.Type,System.Collections.Hashtable)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.ReflectionAwareCodeGen.WriteMappingInfo(System.Xml.Serialization.TypeMapping,System.String,System.Type)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2070</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.ReflectionAwareCodeGen.WriteMemberInfo(System.Type,System.String,System.String,System.String)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
Expand Down Expand Up @@ -193,6 +211,12 @@
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly(System.Type,System.String,System.Xml.Serialization.XmlSerializerImplementation@)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2072</argument>
<property name="Scope">member</property>
<property name="Target">M:System.Xml.Serialization.XmlSerializationILGen.GenerateTypedSerializer(System.String,System.String,System.Xml.Serialization.XmlMapping,System.Xml.Serialization.CodeIdentifiers,System.String,System.String,System.String)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2072</argument>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ namespace System.Xml.Serialization
{
internal class CodeGenerator
{
internal static BindingFlags InstancePublicBindingFlags = BindingFlags.Instance | BindingFlags.Public;
internal static BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
internal static BindingFlags StaticBindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
internal static MethodAttributes PublicMethodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig;
internal static MethodAttributes PublicOverrideMethodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
internal static MethodAttributes ProtectedOverrideMethodAttributes = MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig;
internal static MethodAttributes PrivateMethodAttributes = MethodAttributes.Private | MethodAttributes.HideBySig;
internal const BindingFlags InstancePublicBindingFlags = BindingFlags.Instance | BindingFlags.Public;
internal const BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
internal const BindingFlags StaticBindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
internal const MethodAttributes PublicMethodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig;
internal const MethodAttributes PublicOverrideMethodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
internal const MethodAttributes ProtectedOverrideMethodAttributes = MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig;
internal const MethodAttributes PrivateMethodAttributes = MethodAttributes.Private | MethodAttributes.HideBySig;

private readonly TypeBuilder _typeBuilder;
private MethodBuilder? _methodBuilder;
Expand Down Expand Up @@ -1242,7 +1242,13 @@ internal static ModuleBuilder CreateModuleBuilder(AssemblyBuilder assemblyBuilde
{
return assemblyBuilder.DefineDynamicModule(name);
}
internal static TypeBuilder CreateTypeBuilder(ModuleBuilder moduleBuilder, string name, TypeAttributes attributes, Type parent, Type[] interfaces)

internal static TypeBuilder CreateTypeBuilder(
ModuleBuilder moduleBuilder,
string name,
TypeAttributes attributes,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type parent,
Type[] interfaces)
{
// parent is nullable if no base class
return moduleBuilder.DefineType(TempAssembly.GeneratedAssemblyNamespace + "." + name,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project DefaultTargets="Build">
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))" />

<ItemGroup>
<TestConsoleAppSourceFiles Include="XmlSerializer.Deserialize.cs" />
<TestConsoleAppSourceFiles Include="XmlSerializer.Serialize.cs" />
</ItemGroup>

<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.targets))" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Xml.Schema;

namespace System.Xml.Serialization.TrimmingTests
{
internal class Program
{
// Preserve these types until XmlSerializer is fully trim-safe.
// see https://github.com/dotnet/runtime/issues/44768
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Response))]
joperezr marked this conversation as resolved.
Show resolved Hide resolved
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DataUpdates))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DataUpdatesDataUpdateInfo))]
public static int Main()
{
using StringReader stringReader = new StringReader(@"<?xml version=""1.0"" encoding=""UTF-8""?>
<Response>
<DataUpdates>
<DataUpdateInfo DataDate=""2009-04-13T00:00:00"" DataType=""Data"" LastUpdatedDate=""2010-12-12T02:53:19.257"" />
<DataUpdateInfo DataDate=""2009-04-14T00:00:00"" DataType=""Data"" LastUpdatedDate=""2010-12-12T02:53:19.257"" />
<DataUpdateInfo DataDate=""2009-04-15T00:00:00"" DataType=""Data"" LastUpdatedDate=""2010-12-12T01:52:51.047"" />
</DataUpdates>
</Response>");

Response obj = (Response)new XmlSerializer(typeof(Response)).Deserialize(stringReader);
if (obj.DataUpdates.DataUpdateInfo.Count == 3 &&
obj.DataUpdates.DataUpdateInfo.All(i => i.DataDate.Year == 2009 && i.LastUpdatedDate.Year == 2010))
{
return 100;
}

return -1;
}
}

[Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public class Response
{
public Response()
{
this.DataUpdates = new DataUpdates();
}

[XmlElement(Order = 0)]
public DataUpdates DataUpdates { get; set; }
}

[Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public class DataUpdates
{
public DataUpdates()
{
this.DataUpdateInfo = new List<DataUpdatesDataUpdateInfo>();
}

[XmlElement("DataUpdateInfo", Form = XmlSchemaForm.Unqualified, Order = 0)]
public List<DataUpdatesDataUpdateInfo> DataUpdateInfo { get; set; }
}

[Serializable]
[XmlType(AnonymousType = true)]
public class DataUpdatesDataUpdateInfo
{
public DataUpdatesDataUpdateInfo()
{
}

[XmlAttribute]
public DateTime DataDate { get; set; }

[XmlAttribute]
public string DataType { get; set; }

[XmlAttribute]
public DateTime LastUpdatedDate { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Xml.Schema;

namespace System.Xml.Serialization.TrimmingTests
{
internal class Program
{
// Preserve these types until XmlSerializer is fully trim-safe.
// see https://github.com/dotnet/runtime/issues/44768
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Response))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DataUpdates))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DataUpdatesDataUpdateInfo))]
public static int Main()
{
Response obj = new Response();
obj.DataUpdates.DataUpdateInfo.Add(new DataUpdatesDataUpdateInfo()
{
DataDate = new DateTime(2009, 4, 13),
DataType = "Data",
LastUpdatedDate = new DateTime(2010, 12, 12)
});
obj.DataUpdates.DataUpdateInfo.Add(new DataUpdatesDataUpdateInfo()
{
DataDate = new DateTime(2009, 4, 14),
DataType = "Data",
LastUpdatedDate = new DateTime(2010, 12, 12)
});

using StringWriter writer = new StringWriter();
new XmlSerializer(typeof(Response)).Serialize(writer, obj);
string serialized = writer.ToString();

if (serialized.Contains("<Response") &&
serialized.Contains("<DataUpdates>") &&
serialized.Contains(@"<DataUpdateInfo DataDate=""2009-04-13T00:00:00"" DataType=""Data"" LastUpdatedDate=""2010-12-12T00:00:00"" />") &&
serialized.Contains(@"<DataUpdateInfo DataDate=""2009-04-14T00:00:00"" DataType=""Data"" LastUpdatedDate=""2010-12-12T00:00:00"" />"))
{
return 100;
}

return -1;
}
}

[Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public class Response
{
public Response()
{
this.DataUpdates = new DataUpdates();
}

[XmlElement(Order = 0)]
public DataUpdates DataUpdates { get; set; }
}

[Serializable]
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "", IsNullable = false)]
public class DataUpdates
{
public DataUpdates()
{
this.DataUpdateInfo = new List<DataUpdatesDataUpdateInfo>();
}

[XmlElement("DataUpdateInfo", Form = XmlSchemaForm.Unqualified, Order = 0)]
public List<DataUpdatesDataUpdateInfo> DataUpdateInfo { get; set; }
}

[Serializable]
[XmlType(AnonymousType = true)]
public class DataUpdatesDataUpdateInfo
{
public DataUpdatesDataUpdateInfo()
{
}

[XmlAttribute]
public DateTime DataDate { get; set; }

[XmlAttribute]
public string DataType { get; set; }

[XmlAttribute]
public DateTime LastUpdatedDate { get; set; }
}
}