diff --git a/src/Microsoft.AspNet.Mvc.Xml/Formatters/XmlDataContractSerializerInputFormatter.cs b/src/Microsoft.AspNet.Mvc.Xml/Formatters/XmlDataContractSerializerInputFormatter.cs
index e725bed1c6..dda0e1a700 100644
--- a/src/Microsoft.AspNet.Mvc.Xml/Formatters/XmlDataContractSerializerInputFormatter.cs
+++ b/src/Microsoft.AspNet.Mvc.Xml/Formatters/XmlDataContractSerializerInputFormatter.cs
@@ -20,6 +20,7 @@ namespace Microsoft.AspNet.Mvc.Xml
///
public class XmlDataContractSerializerInputFormatter : IInputFormatter
{
+ private DataContractSerializerSettings _serializerSettings;
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
///
@@ -33,6 +34,7 @@ namespace Microsoft.AspNet.Mvc.Xml
SupportedMediaTypes = new List();
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/xml"));
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/xml"));
+ _serializerSettings = new DataContractSerializerSettings();
}
///
@@ -73,6 +75,24 @@ namespace Microsoft.AspNet.Mvc.Xml
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
}
+ ///
+ /// Gets or sets the used to configure the
+ /// .
+ ///
+ public DataContractSerializerSettings SerializerSettings
+ {
+ get { return _serializerSettings; }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ _serializerSettings = value;
+ }
+ }
+
///
/// Reads the input XML.
///
@@ -106,7 +126,7 @@ namespace Microsoft.AspNet.Mvc.Xml
/// The used during deserialization.
protected virtual XmlObjectSerializer CreateDataContractSerializer(Type type)
{
- return new DataContractSerializer(SerializableErrorWrapper.CreateSerializableType(type));
+ return new DataContractSerializer(SerializableErrorWrapper.CreateSerializableType(type), _serializerSettings);
}
private object GetDefaultValueForType(Type modelType)
diff --git a/src/Microsoft.AspNet.Mvc.Xml/Formatters/XmlDataContractSerializerOutputFormatter.cs b/src/Microsoft.AspNet.Mvc.Xml/Formatters/XmlDataContractSerializerOutputFormatter.cs
index e132106133..a751f202f9 100644
--- a/src/Microsoft.AspNet.Mvc.Xml/Formatters/XmlDataContractSerializerOutputFormatter.cs
+++ b/src/Microsoft.AspNet.Mvc.Xml/Formatters/XmlDataContractSerializerOutputFormatter.cs
@@ -16,6 +16,8 @@ namespace Microsoft.AspNet.Mvc.Xml
///
public class XmlDataContractSerializerOutputFormatter : OutputFormatter
{
+ private DataContractSerializerSettings _serializerSettings;
+
///
/// Initializes a new instance of
/// with default XmlWriterSettings
@@ -38,6 +40,7 @@ namespace Microsoft.AspNet.Mvc.Xml
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/xml"));
WriterSettings = writerSettings;
+ _serializerSettings = new DataContractSerializerSettings();
}
///
@@ -45,6 +48,24 @@ namespace Microsoft.AspNet.Mvc.Xml
///
public XmlWriterSettings WriterSettings { get; }
+ ///
+ /// Gets or sets the used to configure the
+ /// .
+ ///
+ public DataContractSerializerSettings SerializerSettings
+ {
+ get { return _serializerSettings; }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ _serializerSettings = value;
+ }
+ }
+
///
/// Gets the type of the object to be serialized.
///
@@ -85,7 +106,7 @@ namespace Microsoft.AspNet.Mvc.Xml
FormattingUtilities.XsdDataContractExporter.GetRootElementName(type);
#endif
// If the serializer does not support this type it will throw an exception.
- return new DataContractSerializer(type);
+ return new DataContractSerializer(type, _serializerSettings);
}
catch (Exception)
{
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerInputFormatterTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerInputFormatterTest.cs
index d67cf74186..95dd8baf21 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerInputFormatterTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerInputFormatterTest.cs
@@ -27,6 +27,13 @@ namespace Microsoft.AspNet.Mvc
public int SampleInt { get; set; }
}
+ [DataContract(Name = "SomeDummyClass", Namespace = "")]
+ public class SomeDummyClass : DummyClass
+ {
+ [DataMember]
+ public string SampleString { get; set; }
+ }
+
[DataContract(Name = "TestLevelOne", Namespace = "")]
public class TestLevelOne
{
@@ -359,6 +366,118 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal("Test Error 3", serializableError["key2"]);
}
+ [Fact]
+ public async Task XmlDataContractSerializerFormatterThrowsWhenNotConfiguredWithRootName()
+ {
+ // Arrange
+ var SubstituteRootName = "SomeOtherClass";
+ var SubstituteRootNamespace = "http://tempuri.org";
+
+ var input = string.Format(
+ "<{0} xmlns=\"{1}\">1{0}>",
+ SubstituteRootName,
+ SubstituteRootNamespace);
+ var formatter = new XmlDataContractSerializerInputFormatter();
+ var contentBytes = Encoding.UTF8.GetBytes(input);
+ var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
+
+ // Act & Assert
+ await Assert.ThrowsAsync(typeof(SerializationException), async () => await formatter.ReadAsync(context));
+ }
+
+ [Fact]
+ public async Task XmlDataContractSerializerFormatterReadsWhenConfiguredWithRootName()
+ {
+ // Arrange
+ var expectedInt = 10;
+ var SubstituteRootName = "SomeOtherClass";
+ var SubstituteRootNamespace = "http://tempuri.org";
+
+ var input = string.Format(
+ "<{0} xmlns=\"{1}\">{2}{0}>",
+ SubstituteRootName,
+ SubstituteRootNamespace,
+ expectedInt);
+
+ var dictionary = new XmlDictionary();
+ var settings = new DataContractSerializerSettings
+ {
+ RootName = dictionary.Add(SubstituteRootName),
+ RootNamespace = dictionary.Add(SubstituteRootNamespace)
+ };
+ var formatter = new XmlDataContractSerializerInputFormatter
+ {
+ SerializerSettings = settings
+ };
+ var contentBytes = Encoding.UTF8.GetBytes(input);
+ var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
+
+ // Act
+ var model = await formatter.ReadAsync(context);
+
+ // Assert
+ Assert.NotNull(model);
+ var dummyModel = Assert.IsType(model);
+ Assert.Equal(expectedInt, dummyModel.SampleInt);
+ }
+
+ [Fact]
+ public async Task XmlDataContractSerializerFormatterThrowsWhenNotConfiguredWithKnownTypes()
+ {
+ // Arrange
+ var KnownTypeName = "SomeDummyClass";
+ var InstanceNamespace = "http://www.w3.org/2001/XMLSchema-instance";
+
+ var input = string.Format(
+ "1"
+ + "Some text",
+ KnownTypeName,
+ InstanceNamespace);
+ var formatter = new XmlDataContractSerializerInputFormatter();
+ var contentBytes = Encoding.UTF8.GetBytes(input);
+ var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
+
+ // Act & Assert
+ await Assert.ThrowsAsync(typeof(SerializationException), async () => await formatter.ReadAsync(context));
+ }
+
+ [Fact]
+ public async Task XmlDataContractSerializerFormatterReadsWhenConfiguredWithKnownTypes()
+ {
+ // Arrange
+ var expectedInt = 10;
+ var expectedString = "TestString";
+ var KnownTypeName = "SomeDummyClass";
+ var InstanceNamespace = "http://www.w3.org/2001/XMLSchema-instance";
+
+ var input = string.Format(
+ "{2}"
+ + "{3}",
+ KnownTypeName,
+ InstanceNamespace,
+ expectedInt,
+ expectedString);
+ var settings = new DataContractSerializerSettings
+ {
+ KnownTypes = new[] { typeof(SomeDummyClass) }
+ };
+ var formatter = new XmlDataContractSerializerInputFormatter
+ {
+ SerializerSettings = settings
+ };
+ var contentBytes = Encoding.UTF8.GetBytes(input);
+ var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
+
+ // Act
+ var model = await formatter.ReadAsync(context);
+
+ // Assert
+ Assert.NotNull(model);
+ var dummyModel = Assert.IsType(model);
+ Assert.Equal(expectedInt, dummyModel.SampleInt);
+ Assert.Equal(expectedString, dummyModel.SampleString);
+ }
+
private InputFormatterContext GetInputFormatterContext(byte[] contentBytes, Type modelType)
{
var actionContext = GetActionContext(contentBytes);
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs
index ffdeb14418..cc3d1e9e8e 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs
@@ -7,10 +7,11 @@ using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
+using System.Xml;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Core.Collections;
-using Microsoft.Net.Http.Headers;
using Microsoft.AspNet.Mvc.Xml;
+using Microsoft.Net.Http.Headers;
using Moq;
using Xunit;
@@ -25,6 +26,13 @@ namespace Microsoft.AspNet.Mvc.Core
public int SampleInt { get; set; }
}
+ [DataContract(Name = "SomeDummyClass", Namespace = "")]
+ public class SomeDummyClass : DummyClass
+ {
+ [DataMember]
+ public string SampleString { get; set; }
+ }
+
[DataContract(Name = "TestLevelOne", Namespace = "")]
public class TestLevelOne
{
@@ -43,6 +51,24 @@ namespace Microsoft.AspNet.Mvc.Core
public TestLevelOne TestOne { get; set; }
}
+ [DataContract(Name = "Child", Namespace = "")]
+ public class Child
+ {
+ [DataMember]
+ public int Id { get; set; }
+ [DataMember]
+ public Parent Parent { get; set; }
+ }
+
+ [DataContract(Name = "Parent", Namespace = "")]
+ public class Parent
+ {
+ [DataMember]
+ public string Name { get; set; }
+ [DataMember]
+ public List Children { get; set; }
+ }
+
public static IEnumerable