diff --git a/docs/workflow/trimming/feature-switches.md b/docs/workflow/trimming/feature-switches.md
index 92d04e897a2da1..76714d95f2c2ba 100644
--- a/docs/workflow/trimming/feature-switches.md
+++ b/docs/workflow/trimming/feature-switches.md
@@ -14,6 +14,7 @@ configurations but their defaults might vary as any SDK can set the defaults dif
| VerifyDependencyInjectionOpenGenericServiceTrimmability | Microsoft.Extensions.DependencyInjection.VerifyOpenGenericServiceTrimmability | When set to true, DependencyInjection will verify trimming annotations applied to open generic services are correct. |
| _AggressiveAttributeTrimming | System.AggressiveAttributeTrimming | When set to true, aggressively trims attributes to allow for the most size savings possible, even if it could result in runtime behavior changes |
| _ComObjectDescriptorSupport | System.ComponentModel.TypeDescriptor.IsComObjectDescriptorSupported | When set to true, supports creating a TypeDescriptor based view of COM objects. |
+| _DataSetXmlSerializationSupport | System.Data.DataSet.XmlSerializationIsSupported | When set to false, DataSet implementation of IXmlSerializable will throw instead of using trim-incompatible XML serialization. |
| _DefaultValueAttributeSupport | System.ComponentModel.DefaultValueAttribute.IsSupported | When set to true, supports creating a DefaultValueAttribute at runtime. |
| _DesignerHostSupport | System.ComponentModel.Design.IDesignerHost.IsSupported | When set to true, supports creating design components at runtime. |
| _EnableConsumingManagedCodeFromNativeHosting | System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting | Getting a managed function from native hosting is disabled when set to false and related functionality can be trimmed. |
diff --git a/src/libraries/System.Data.Common/src/Resources/Strings.resx b/src/libraries/System.Data.Common/src/Resources/Strings.resx
index 8c3c530ceb37c4..4b5d9b14a661ea 100644
--- a/src/libraries/System.Data.Common/src/Resources/Strings.resx
+++ b/src/libraries/System.Data.Common/src/Resources/Strings.resx
@@ -527,4 +527,5 @@
The DataRowComparer does not work with DataRows that have been deleted since it only compares current values.
The source contains a deleted DataRow that cannot be copied to the DataTable.
Cannot cast DBNull. Value to type '{0}'. Please use a nullable type.
+ DataSet implementation of IXmlSerializable is not trim compatible and has been disabled in the app configuration.
diff --git a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs
index 37c1fb283d7e19..56fa3c9118f546 100644
--- a/src/libraries/System.Data.Common/src/System/Data/DataSet.cs
+++ b/src/libraries/System.Data.Common/src/System/Data/DataSet.cs
@@ -77,6 +77,12 @@ public class DataSet : MarshalByValueComponent, IListSource, IXmlSerializable, I
internal bool _useDataSetSchemaOnly; // UseDataSetSchemaOnly , for YUKON
internal bool _udtIsWrapped; // if UDT is wrapped , for YUKON
+ [FeatureSwitchDefinition("System.Data.DataSet.XmlSerializationIsSupported")]
+ [FeatureGuard(typeof(RequiresUnreferencedCodeAttribute))]
+#pragma warning disable IL4000
+ internal static bool XmlSerializationIsSupported => AppContext.TryGetSwitch("System.Data.DataSet.XmlSerializationIsSupported", out bool isSupported) ? isSupported : true;
+#pragma warning restore IL4000
+
///
/// Initializes a new instance of the class.
///
@@ -3459,6 +3465,11 @@ public static XmlSchemaComplexType GetDataSetSchema(XmlSchemaSet? schemaSet)
XmlSchema? IXmlSerializable.GetSchema()
{
+ if (!XmlSerializationIsSupported)
+ {
+ throw new NotSupportedException(SR.DataSet_XmlSerializationUnsupported);
+ }
+
if (GetType() == typeof(DataSet))
{
return null;
@@ -3469,9 +3480,7 @@ public static XmlSchemaComplexType GetDataSetSchema(XmlSchemaSet? schemaSet)
XmlWriter writer = new XmlTextWriter(stream, null);
if (writer != null)
{
-#pragma warning disable IL2026 // suppressed in ILLink.Suppressions.LibraryBuild.xml
WriteXmlSchema(this, writer);
-#pragma warning restore IL2026
}
stream.Position = 0;
return XmlSchema.Read(new XmlTextReader(stream), null);
@@ -3485,6 +3494,11 @@ private static void WriteXmlSchema(DataSet ds, XmlWriter writer)
void IXmlSerializable.ReadXml(XmlReader reader)
{
+ if (!XmlSerializationIsSupported)
+ {
+ throw new NotSupportedException(SR.DataSet_XmlSerializationUnsupported);
+ }
+
bool fNormalization = true;
XmlTextReader? xmlTextReader = null;
IXmlTextParser? xmlTextParser = reader as IXmlTextParser;
@@ -3503,9 +3517,7 @@ void IXmlSerializable.ReadXml(XmlReader reader)
}
}
-#pragma warning disable IL2026 // suppressed in ILLink.Suppressions.LibraryBuild.xml
ReadXmlSerializableInternal(reader);
-#pragma warning restore IL2026
if (xmlTextParser != null)
{
@@ -3525,9 +3537,12 @@ private void ReadXmlSerializableInternal(XmlReader reader)
void IXmlSerializable.WriteXml(XmlWriter writer)
{
-#pragma warning disable IL2026 // suppressed in ILLink.Suppressions.LibraryBuild.xml
+ if (!XmlSerializationIsSupported)
+ {
+ throw new NotSupportedException(SR.DataSet_XmlSerializationUnsupported);
+ }
+
WriteXmlInternal(writer);
-#pragma warning restore IL2026
}
[RequiresUnreferencedCode("DataSet.WriteXml uses XmlSerialization underneath which is not trimming safe. Members from serialized types may be trimmed if not referenced directly.")]
diff --git a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs
index dedde6f7efbd62..ab92707b1c2089 100644
--- a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs
+++ b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs
@@ -6664,9 +6664,15 @@ public static XmlSchemaComplexType GetDataTableSchema(XmlSchemaSet? schemaSet)
return type;
}
-#pragma warning disable IL2026 // suppressed in ILLink.Suppressions.LibraryBuild.xml
- XmlSchema? IXmlSerializable.GetSchema() => GetXmlSchema();
-#pragma warning restore IL2026
+ XmlSchema? IXmlSerializable.GetSchema()
+ {
+ if (!DataSet.XmlSerializationIsSupported)
+ {
+ throw new NotSupportedException(SR.DataSet_XmlSerializationUnsupported);
+ }
+
+ return GetXmlSchema();
+ }
[RequiresUnreferencedCode(DataSet.RequiresUnreferencedCodeMessage)]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2046:UnrecognizedReflectionPattern",
@@ -6693,6 +6699,11 @@ public static XmlSchemaComplexType GetDataTableSchema(XmlSchemaSet? schemaSet)
void IXmlSerializable.ReadXml(XmlReader reader)
{
+ if (!DataSet.XmlSerializationIsSupported)
+ {
+ throw new NotSupportedException(SR.DataSet_XmlSerializationUnsupported);
+ }
+
IXmlTextParser? textReader = reader as IXmlTextParser;
bool fNormalization = true;
if (textReader != null)
@@ -6700,9 +6711,7 @@ void IXmlSerializable.ReadXml(XmlReader reader)
fNormalization = textReader.Normalized;
textReader.Normalized = false;
}
-#pragma warning disable IL2026 // suppressed in ILLink.Suppressions.LibraryBuild.xml
ReadXmlSerializableInternal(reader);
-#pragma warning restore IL2026
if (textReader != null)
{
@@ -6718,9 +6727,12 @@ private void ReadXmlSerializableInternal(XmlReader reader)
void IXmlSerializable.WriteXml(XmlWriter writer)
{
-#pragma warning disable IL2026 // suppressed in ILLink.Suppressions.LibraryBuild.xml
+ if (!DataSet.XmlSerializationIsSupported)
+ {
+ throw new NotSupportedException(SR.DataSet_XmlSerializationUnsupported);
+ }
+
WriteXmlInternal(writer);
-#pragma warning restore IL2026
}
[RequiresUnreferencedCode("DataTable.WriteXml uses XmlSerialization underneath which is not trimming safe. Members from serialized types may be trimmed if not referenced directly.")]
diff --git a/src/libraries/System.Data.Common/tests/TrimmingTests/DataSetXmlSerialization.cs b/src/libraries/System.Data.Common/tests/TrimmingTests/DataSetXmlSerialization.cs
new file mode 100644
index 00000000000000..502133d912ddf6
--- /dev/null
+++ b/src/libraries/System.Data.Common/tests/TrimmingTests/DataSetXmlSerialization.cs
@@ -0,0 +1,82 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Data;
+using System.Xml.Schema;
+using System.Xml.Serialization;
+
+namespace DataSetXmlSerializationTrimmingTests
+{
+ class Program
+ {
+ static int Main(string[] args)
+ {
+ IXmlSerializable xmlSerializable = new DataSet();
+
+ // Calling GetSchema should throw NotSupportedException
+ try
+ {
+ xmlSerializable.GetSchema();
+ return -1;
+ }
+ catch (NotSupportedException)
+ {
+ }
+
+ // Calling ReadXml should throw NotSupportedException
+ try
+ {
+ xmlSerializable.ReadXml(null);
+ return -2;
+ }
+ catch (NotSupportedException)
+ {
+ }
+
+ // Calling WriteXml should throw NotSupportedException
+ try
+ {
+ xmlSerializable.WriteXml(null);
+ return -3;
+ }
+ catch (NotSupportedException)
+ {
+ }
+
+ xmlSerializable = new DataTable();
+
+ // Calling GetSchema should throw NotSupportedException
+ try
+ {
+ xmlSerializable.GetSchema();
+ return -4;
+ }
+ catch (NotSupportedException)
+ {
+ }
+
+ // Calling ReadXml should throw NotSupportedException
+ try
+ {
+ xmlSerializable.ReadXml(null);
+ return -5;
+ }
+ catch (NotSupportedException)
+ {
+ }
+
+ // Calling WriteXml should throw NotSupportedException
+ try
+ {
+ xmlSerializable.WriteXml(null);
+ return -6;
+ }
+ catch (NotSupportedException)
+ {
+ }
+
+ return 100;
+ }
+ }
+}
diff --git a/src/libraries/System.Data.Common/tests/TrimmingTests/System.Data.Common.TrimmingTests.proj b/src/libraries/System.Data.Common/tests/TrimmingTests/System.Data.Common.TrimmingTests.proj
index 7254c33fc9c7ba..9d59bb0f97e146 100644
--- a/src/libraries/System.Data.Common/tests/TrimmingTests/System.Data.Common.TrimmingTests.proj
+++ b/src/libraries/System.Data.Common/tests/TrimmingTests/System.Data.Common.TrimmingTests.proj
@@ -4,6 +4,9 @@
+
+ System.Data.DataSet.XmlSerializationIsSupported
+
diff --git a/src/tools/illink/src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets b/src/tools/illink/src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets
index ab36c6795a4b0c..3fdf083a3beda8 100644
--- a/src/tools/illink/src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets
+++ b/src/tools/illink/src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets
@@ -57,6 +57,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<_DefaultValueAttributeSupport Condition="'$(_DefaultValueAttributeSupport)' == ''">false
true
false
+ <_DataSetXmlSerializationSupport Condition="'$(_DataSetXmlSerializationSupport)' == ''">false