Fix Xml formatters to taking in MvcOptions to take affect of options mutation

Related to issue [Fixes #6858] Changes to MvcOption's settings (SuppressInputFormatterBuffering & AllowBindingUndefinedValueToEnumType) are not taking affect
This commit is contained in:
Kiran Challa 2017-12-04 17:04:02 -08:00
parent e09ea40551
commit db38da7edb
8 changed files with 396 additions and 89 deletions

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml.Internal
options.ModelMetadataDetailsProviders.Add(new DataMemberRequiredBindingMetadataProvider()); options.ModelMetadataDetailsProviders.Add(new DataMemberRequiredBindingMetadataProvider());
options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter()); options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
options.InputFormatters.Add(new XmlDataContractSerializerInputFormatter(options.SuppressInputFormatterBuffering)); options.InputFormatters.Add(new XmlDataContractSerializerInputFormatter(options));
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider("System.Xml.Linq.XObject")); options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider("System.Xml.Linq.XObject"));
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider("System.Xml.XmlNode")); options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider("System.Xml.XmlNode"));

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml.Internal
public void Configure(MvcOptions options) public void Configure(MvcOptions options)
{ {
options.OutputFormatters.Add(new XmlSerializerOutputFormatter()); options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
options.InputFormatters.Add(new XmlSerializerInputFormatter(options.SuppressInputFormatterBuffering)); options.InputFormatters.Add(new XmlSerializerInputFormatter(options));
} }
} }
} }

View File

@ -28,24 +28,15 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
private readonly ConcurrentDictionary<Type, object> _serializerCache = new ConcurrentDictionary<Type, object>(); private readonly ConcurrentDictionary<Type, object> _serializerCache = new ConcurrentDictionary<Type, object>();
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas(); private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
private readonly bool _suppressInputFormatterBuffering; private readonly bool _suppressInputFormatterBuffering;
private readonly MvcOptions _options;
private DataContractSerializerSettings _serializerSettings; private DataContractSerializerSettings _serializerSettings;
/// <summary> /// <summary>
/// Initializes a new instance of DataContractSerializerInputFormatter /// Initializes a new instance of <see cref="XmlDataContractSerializerInputFormatter"/>.
/// </summary> /// </summary>
public XmlDataContractSerializerInputFormatter() : [Obsolete("This constructor is obsolete and will be removed in a future version.")]
this(suppressInputFormatterBuffering: false) public XmlDataContractSerializerInputFormatter()
{ {
}
/// <summary>
/// Initializes a new instance of DataContractSerializerInputFormatter
/// </summary>
/// <param name="suppressInputFormatterBuffering">Flag to buffer entire request body before deserializing it.</param>
public XmlDataContractSerializerInputFormatter(bool suppressInputFormatterBuffering)
{
_suppressInputFormatterBuffering = suppressInputFormatterBuffering;
SupportedEncodings.Add(UTF8EncodingWithoutBOM); SupportedEncodings.Add(UTF8EncodingWithoutBOM);
SupportedEncodings.Add(UTF16EncodingLittleEndian); SupportedEncodings.Add(UTF16EncodingLittleEndian);
@ -59,6 +50,29 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
WrapperProviderFactories.Add(new SerializableErrorWrapperProviderFactory()); WrapperProviderFactories.Add(new SerializableErrorWrapperProviderFactory());
} }
/// <summary>
/// Initializes a new instance of <see cref="XmlDataContractSerializerInputFormatter"/>.
/// </summary>
/// <param name="suppressInputFormatterBuffering">Flag to buffer entire request body before deserializing it.</param>
[Obsolete("This constructor is obsolete and will be removed in a future version.")]
public XmlDataContractSerializerInputFormatter(bool suppressInputFormatterBuffering)
: this()
{
_suppressInputFormatterBuffering = suppressInputFormatterBuffering;
}
/// <summary>
/// Initializes a new instance of <see cref="XmlDataContractSerializerInputFormatter"/>.
/// </summary>
/// <param name="options">The <see cref="MvcOptions"/>.</param>
public XmlDataContractSerializerInputFormatter(MvcOptions options)
#pragma warning disable CS0618
: this()
#pragma warning restore CS0618
{
_options = options;
}
/// <summary> /// <summary>
/// Gets the list of <see cref="IWrapperProviderFactory"/> to /// Gets the list of <see cref="IWrapperProviderFactory"/> to
/// provide the wrapping type for de-serialization. /// provide the wrapping type for de-serialization.
@ -126,7 +140,9 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
var request = context.HttpContext.Request; var request = context.HttpContext.Request;
if (!request.Body.CanSeek && !_suppressInputFormatterBuffering) var suppressInputFormatterBuffering = _options?.SuppressInputFormatterBuffering ?? _suppressInputFormatterBuffering;
if (!request.Body.CanSeek && !suppressInputFormatterBuffering)
{ {
// XmlDataContractSerializer does synchronous reads. In order to avoid blocking on the stream, we asynchronously // XmlDataContractSerializer does synchronous reads. In order to avoid blocking on the stream, we asynchronously
// read everything into a buffer, and then seek back to the beginning. // read everything into a buffer, and then seek back to the beginning.

View File

@ -28,23 +28,14 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
private readonly ConcurrentDictionary<Type, object> _serializerCache = new ConcurrentDictionary<Type, object>(); private readonly ConcurrentDictionary<Type, object> _serializerCache = new ConcurrentDictionary<Type, object>();
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas(); private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
private readonly bool _suppressInputFormatterBuffering; private readonly bool _suppressInputFormatterBuffering;
private readonly MvcOptions _options;
/// <summary> /// <summary>
/// Initializes a new instance of XmlSerializerInputFormatter. /// Initializes a new instance of XmlSerializerInputFormatter.
/// </summary> /// </summary>
[Obsolete("This constructor is obsolete and will be removed in a future version.")]
public XmlSerializerInputFormatter() public XmlSerializerInputFormatter()
: this(suppressInputFormatterBuffering: false)
{ {
}
/// <summary>
/// Initializes a new instance of XmlSerializerInputFormatter.
/// </summary>
/// <param name="suppressInputFormatterBuffering">Flag to buffer entire request body before deserializing it.</param>
public XmlSerializerInputFormatter(bool suppressInputFormatterBuffering)
{
_suppressInputFormatterBuffering = suppressInputFormatterBuffering;
SupportedEncodings.Add(UTF8EncodingWithoutBOM); SupportedEncodings.Add(UTF8EncodingWithoutBOM);
SupportedEncodings.Add(UTF16EncodingLittleEndian); SupportedEncodings.Add(UTF16EncodingLittleEndian);
@ -56,6 +47,29 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
WrapperProviderFactories.Add(new SerializableErrorWrapperProviderFactory()); WrapperProviderFactories.Add(new SerializableErrorWrapperProviderFactory());
} }
/// <summary>
/// Initializes a new instance of <see cref="XmlSerializerInputFormatter"/>.
/// </summary>
/// <param name="suppressInputFormatterBuffering">Flag to buffer entire request body before deserializing it.</param>
[Obsolete("This constructor is obsolete and will be removed in a future version.")]
public XmlSerializerInputFormatter(bool suppressInputFormatterBuffering)
: this()
{
_suppressInputFormatterBuffering = suppressInputFormatterBuffering;
}
/// <summary>
/// Initializes a new instance of <see cref="XmlSerializerInputFormatter"/>.
/// </summary>
/// <param name="options">The <see cref="MvcOptions"/>.</param>
public XmlSerializerInputFormatter(MvcOptions options)
#pragma warning disable CS0618
: this()
#pragma warning restore CS0618
{
_options = options;
}
/// <summary> /// <summary>
/// Gets the list of <see cref="IWrapperProviderFactory"/> to /// Gets the list of <see cref="IWrapperProviderFactory"/> to
/// provide the wrapping type for de-serialization. /// provide the wrapping type for de-serialization.
@ -107,7 +121,9 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
var request = context.HttpContext.Request; var request = context.HttpContext.Request;
if (!request.Body.CanSeek && !_suppressInputFormatterBuffering) var suppressInputFormatterBuffering = _options?.SuppressInputFormatterBuffering ?? _suppressInputFormatterBuffering;
if (!request.Body.CanSeek && !suppressInputFormatterBuffering)
{ {
// XmlSerializer does synchronous reads. In order to avoid blocking on the stream, we asynchronously // XmlSerializer does synchronous reads. In order to avoid blocking on the stream, we asynchronously
// read everything into a buffer, and then seek back to the beginning. // read everything into a buffer, and then seek back to the beginning.

View File

@ -243,10 +243,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
{ {
return new TheoryData<IInputFormatter, InputFormatterExceptionModelStatePolicy>() return new TheoryData<IInputFormatter, InputFormatterExceptionModelStatePolicy>()
{ {
{ new XmlSerializerInputFormatter(), InputFormatterExceptionModelStatePolicy.AllExceptions }, { new XmlSerializerInputFormatter(new MvcOptions()), InputFormatterExceptionModelStatePolicy.AllExceptions },
{ new XmlSerializerInputFormatter(), InputFormatterExceptionModelStatePolicy.MalformedInputExceptions }, { new XmlSerializerInputFormatter(new MvcOptions()), InputFormatterExceptionModelStatePolicy.MalformedInputExceptions },
{ new XmlDataContractSerializerInputFormatter(), InputFormatterExceptionModelStatePolicy.AllExceptions }, { new XmlDataContractSerializerInputFormatter(new MvcOptions()), InputFormatterExceptionModelStatePolicy.AllExceptions },
{ new XmlDataContractSerializerInputFormatter(), InputFormatterExceptionModelStatePolicy.MalformedInputExceptions }, { new XmlDataContractSerializerInputFormatter(new MvcOptions()), InputFormatterExceptionModelStatePolicy.MalformedInputExceptions },
}; };
} }
} }
@ -821,6 +821,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
private bool _throwNonInputFormatterException; private bool _throwNonInputFormatterException;
public TestableXmlSerializerInputFormatter(bool throwNonInputFormatterException) public TestableXmlSerializerInputFormatter(bool throwNonInputFormatterException)
: base(new MvcOptions())
{ {
_throwNonInputFormatterException = throwNonInputFormatterException; _throwNonInputFormatterException = throwNonInputFormatterException;
} }
@ -842,6 +843,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
private bool _throwNonInputFormatterException; private bool _throwNonInputFormatterException;
public TestableXmlDataContractSerializerInputFormatter(bool throwNonInputFormatterException) public TestableXmlDataContractSerializerInputFormatter(bool throwNonInputFormatterException)
: base(new MvcOptions())
{ {
_throwNonInputFormatterException = throwNonInputFormatterException; _throwNonInputFormatterException = throwNonInputFormatterException;
} }
@ -885,6 +887,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
private bool _throwNonInputFormatterException; private bool _throwNonInputFormatterException;
public DerivedXmlSerializerInputFormatter(bool throwNonInputFormatterException) public DerivedXmlSerializerInputFormatter(bool throwNonInputFormatterException)
: base(new MvcOptions())
{ {
_throwNonInputFormatterException = throwNonInputFormatterException; _throwNonInputFormatterException = throwNonInputFormatterException;
} }
@ -906,6 +909,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
private bool _throwNonInputFormatterException; private bool _throwNonInputFormatterException;
public DerivedXmlDataContractSerializerInputFormatter(bool throwNonInputFormatterException) public DerivedXmlDataContractSerializerInputFormatter(bool throwNonInputFormatterException)
: base(new MvcOptions())
{ {
_throwNonInputFormatterException = throwNonInputFormatterException; _throwNonInputFormatterException = throwNonInputFormatterException;
} }

View File

@ -71,7 +71,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentType, bool expectedCanRead) public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentType, bool expectedCanRead)
{ {
// Arrange // Arrange
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes("content"); var contentBytes = Encoding.UTF8.GetBytes("content");
var modelState = new ModelStateDictionary(); var modelState = new ModelStateDictionary();
@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
public void HasProperSuppportedMediaTypes() public void HasProperSuppportedMediaTypes()
{ {
// Arrange & Act // Arrange & Act
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
// Assert // Assert
Assert.Contains("application/xml", formatter.SupportedMediaTypes Assert.Contains("application/xml", formatter.SupportedMediaTypes
@ -127,7 +127,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
public void HasProperSuppportedEncodings() public void HasProperSuppportedEncodings()
{ {
// Arrange & Act // Arrange & Act
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
// Assert // Assert
Assert.Contains(formatter.SupportedEncodings, i => i.WebName == "utf-8"); Assert.Contains(formatter.SupportedEncodings, i => i.WebName == "utf-8");
@ -142,10 +142,13 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var expectedString = "TestString"; var expectedString = "TestString";
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" + "<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString></TestLevelOne>"; "<sampleString>" + expectedString + "</sampleString></TestLevelOne>";
#pragma warning disable CS0618
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter();
#pragma warning restore CS0618
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext(); var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature()); httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
@ -186,10 +189,92 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var expectedString = "TestString"; var expectedString = "TestString";
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" + "<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString></TestLevelOne>"; "<sampleString>" + expectedString + "</sampleString></TestLevelOne>";
#pragma warning disable CS0618
var formatter = new XmlDataContractSerializerInputFormatter(suppressInputFormatterBuffering: true); var formatter = new XmlDataContractSerializerInputFormatter(suppressInputFormatterBuffering: true);
#pragma warning restore CS0618
var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
httpContext.Request.Body = new NonSeekableReadStream(contentBytes);
httpContext.Request.ContentType = "application/xml";
var context = GetInputFormatterContext(httpContext, typeof(TestLevelOne));
// Act
var result = await formatter.ReadAsync(context);
// Assert
Assert.NotNull(result);
Assert.False(result.HasError);
var model = Assert.IsType<TestLevelOne>(result.Model);
Assert.Equal(expectedInt, model.SampleInt);
Assert.Equal(expectedString, model.sampleString);
// Reading again should fail as buffering request body is disabled
await Assert.ThrowsAsync<XmlException>(() => formatter.ReadAsync(context));
}
[Fact]
public async Task BuffersRequestBody_ByDefaultUsingMvcOptions()
{
// Arrange
var expectedInt = 10;
var expectedString = "TestString";
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString></TestLevelOne>";
var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
httpContext.Request.Body = new NonSeekableReadStream(contentBytes);
httpContext.Request.ContentType = "application/json";
var context = GetInputFormatterContext(httpContext, typeof(TestLevelOne));
// Act
var result = await formatter.ReadAsync(context);
// Assert
Assert.NotNull(result);
Assert.False(result.HasError);
var model = Assert.IsType<TestLevelOne>(result.Model);
Assert.Equal(expectedInt, model.SampleInt);
Assert.Equal(expectedString, model.sampleString);
Assert.True(httpContext.Request.Body.CanSeek);
httpContext.Request.Body.Seek(0L, SeekOrigin.Begin);
result = await formatter.ReadAsync(context);
// Assert
Assert.NotNull(result);
Assert.False(result.HasError);
model = Assert.IsType<TestLevelOne>(result.Model);
Assert.Equal(expectedInt, model.SampleInt);
Assert.Equal(expectedString, model.sampleString);
}
[Fact]
public async Task SuppressInputFormatterBufferingSetToTrue_DoesNotBufferRequestBody_UsingMvcOptions()
{
// Arrange
var expectedInt = 10;
var expectedString = "TestString";
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString></TestLevelOne>";
var formatter = new XmlDataContractSerializerInputFormatter(
new MvcOptions() { SuppressInputFormatterBuffering = true });
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext(); var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature()); httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
@ -220,10 +305,10 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var expectedString = "TestString"; var expectedString = "TestString";
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" + "<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString></TestLevelOne>"; "<sampleString>" + expectedString + "</sampleString></TestLevelOne>";
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelOne)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelOne));
@ -239,6 +324,43 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
Assert.Equal(expectedString, model.sampleString); Assert.Equal(expectedString, model.sampleString);
} }
[Fact]
public async Task SuppressInputFormatterBufferingSetToTrue_UsingMutatedOptions()
{
// Arrange
var expectedInt = 10;
var expectedString = "TestString";
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString></TestLevelOne>";
var mvcOptions = new MvcOptions() { SuppressInputFormatterBuffering = false };
var formatter = new XmlDataContractSerializerInputFormatter(mvcOptions);
var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
httpContext.Request.Body = new NonSeekableReadStream(contentBytes);
httpContext.Request.ContentType = "application/xml";
var context = GetInputFormatterContext(httpContext, typeof(TestLevelOne));
// Act
// Mutate options after passing into the constructor to make sure that the value type is not store in the constructor
mvcOptions.SuppressInputFormatterBuffering = true;
var result = await formatter.ReadAsync(context);
// Assert
Assert.NotNull(result);
Assert.False(result.HasError);
var model = Assert.IsType<TestLevelOne>(result.Model);
Assert.Equal(expectedInt, model.SampleInt);
Assert.Equal(expectedString, model.sampleString);
// Reading again should fail as buffering request body is disabled
await Assert.ThrowsAsync<XmlException>(() => formatter.ReadAsync(context));
}
[Fact] [Fact]
public async Task ReadAsync_ReadsComplexTypes() public async Task ReadAsync_ReadsComplexTypes()
{ {
@ -248,11 +370,11 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var expectedLevelTwoString = "102"; var expectedLevelTwoString = "102";
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelTwo><SampleString>" + expectedLevelTwoString + "</SampleString>" + "<TestLevelTwo><SampleString>" + expectedLevelTwoString + "</SampleString>" +
"<TestOne><SampleInt>" + expectedInt + "</SampleInt>" + "<TestOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString></TestOne></TestLevelTwo>"; "<sampleString>" + expectedString + "</sampleString></TestOne></TestLevelTwo>";
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
@ -277,7 +399,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<DummyClass><SampleInt>" + expectedInt + "</SampleInt></DummyClass>"; "<DummyClass><SampleInt>" + expectedInt + "</SampleInt></DummyClass>";
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
formatter.MaxDepth = 10; formatter.MaxDepth = 10;
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass)); var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
@ -298,10 +420,9 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
{ {
// Arrange // Arrange
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelTwo><SampleString>test</SampleString>" + "<TestLevelTwo><SampleString>test</SampleString>" +
"<TestOne><SampleInt>10</SampleInt>" + "<TestOne><SampleInt>10</SampleInt><sampleString>test</sampleString></TestOne></TestLevelTwo>";
"<sampleString>test</sampleString></TestOne></TestLevelTwo>"; var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var formatter = new XmlDataContractSerializerInputFormatter();
formatter.MaxDepth = 1; formatter.MaxDepth = 1;
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
@ -315,10 +436,9 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
{ {
// Arrange // Arrange
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelTwo><SampleString>test</SampleString>" + "<TestLevelTwo><SampleString>test</SampleString><TestOne><SampleInt>10</SampleInt>" +
"<TestOne><SampleInt>10</SampleInt>" + "<sampleString>test</sampleString></TestOne></TestLevelTwo>";
"<sampleString>test</sampleString></TestOne></TestLevelTwo>"; var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var formatter = new XmlDataContractSerializerInputFormatter();
formatter.XmlDictionaryReaderQuotas.MaxStringContentLength = 2; formatter.XmlDictionaryReaderQuotas.MaxStringContentLength = 2;
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
@ -331,7 +451,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
public void SetMaxDepth_ThrowsWhenMaxDepthIsBelowOne() public void SetMaxDepth_ThrowsWhenMaxDepthIsBelowOne()
{ {
// Arrange // Arrange
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
// Act & Assert // Act & Assert
Assert.Throws<ArgumentException>(() => formatter.MaxDepth = 0); Assert.Throws<ArgumentException>(() => formatter.MaxDepth = 0);
@ -343,7 +463,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
// Arrange // Arrange
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<DummyClass><SampleInt>10</SampleInt></DummyClass>"; "<DummyClass><SampleInt>10</SampleInt></DummyClass>";
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass)); var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
@ -372,7 +492,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
Buffer.BlockCopy(inp, 0, contentBytes, inpStart.Length, inp.Length); Buffer.BlockCopy(inp, 0, contentBytes, inpStart.Length, inp.Length);
Buffer.BlockCopy(inpEnd, 0, contentBytes, inpStart.Length + inp.Length, inpEnd.Length); Buffer.BlockCopy(inpEnd, 0, contentBytes, inpStart.Length + inp.Length, inpEnd.Length);
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
// Act // Act
@ -390,7 +510,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var inputBytes = Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var inputBytes = Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<DummyClass><SampleInt>1000</SampleInt></DummyClass>"); "<DummyClass><SampleInt>1000</SampleInt></DummyClass>");
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var modelState = new ModelStateDictionary(); var modelState = new ModelStateDictionary();
var httpContext = GetHttpContext(inputBytes, contentType: "application/xml; charset=utf-16"); var httpContext = GetHttpContext(inputBytes, contentType: "application/xml; charset=utf-16");
@ -427,7 +547,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
Buffer.BlockCopy(bom, 0, contentBytes, inputStart.Length, bom.Length); Buffer.BlockCopy(bom, 0, contentBytes, inputStart.Length, bom.Length);
Buffer.BlockCopy(inputEnd, 0, contentBytes, inputStart.Length + bom.Length, inputEnd.Length); Buffer.BlockCopy(inputEnd, 0, contentBytes, inputStart.Length + bom.Length, inputEnd.Length);
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
// Act // Act
@ -453,7 +573,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" + "<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString></TestLevelOne>"; "<sampleString>" + expectedString + "</sampleString></TestLevelOne>";
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.Unicode.GetBytes(input); var contentBytes = Encoding.Unicode.GetBytes(input);
var modelState = new ModelStateDictionary(); var modelState = new ModelStateDictionary();
@ -491,7 +611,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
"<{0} xmlns=\"{1}\"><SampleInt xmlns=\"\">1</SampleInt></{0}>", "<{0} xmlns=\"{1}\"><SampleInt xmlns=\"\">1</SampleInt></{0}>",
SubstituteRootName, SubstituteRootName,
SubstituteRootNamespace); SubstituteRootNamespace);
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass)); var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
@ -519,7 +639,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
RootName = dictionary.Add(SubstituteRootName), RootName = dictionary.Add(SubstituteRootName),
RootNamespace = dictionary.Add(SubstituteRootNamespace) RootNamespace = dictionary.Add(SubstituteRootNamespace)
}; };
var formatter = new XmlDataContractSerializerInputFormatter var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions())
{ {
SerializerSettings = settings SerializerSettings = settings
}; };
@ -548,7 +668,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
+ "<SampleString>Some text</SampleString></DummyClass>", + "<SampleString>Some text</SampleString></DummyClass>",
KnownTypeName, KnownTypeName,
InstanceNamespace); InstanceNamespace);
var formatter = new XmlDataContractSerializerInputFormatter(); var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass)); var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
@ -576,7 +696,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
{ {
KnownTypes = new[] { typeof(SomeDummyClass) } KnownTypes = new[] { typeof(SomeDummyClass) }
}; };
var formatter = new XmlDataContractSerializerInputFormatter var formatter = new XmlDataContractSerializerInputFormatter(new MvcOptions())
{ {
SerializerSettings = settings SerializerSettings = settings
}; };
@ -632,6 +752,11 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
{ {
public int createSerializerCalledCount = 0; public int createSerializerCalledCount = 0;
public TestXmlDataContractSerializerInputFormatter()
: base(new MvcOptions())
{
}
protected override DataContractSerializer CreateSerializer(Type type) protected override DataContractSerializer CreateSerializer(Type type)
{ {
createSerializerCalledCount++; createSerializerCalledCount++;

View File

@ -49,11 +49,108 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var expectedDateTime = XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc); var expectedDateTime = XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc);
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" + "<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString>" + "<sampleString>" + expectedString + "</sampleString>" +
"<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>"; "<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>";
#pragma warning disable CS0618
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter();
#pragma warning restore CS0618
var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
httpContext.Request.Body = new NonSeekableReadStream(contentBytes);
httpContext.Request.ContentType = "application/json";
var context = GetInputFormatterContext(httpContext, typeof(TestLevelOne));
// Act
var result = await formatter.ReadAsync(context);
// Assert
Assert.NotNull(result);
Assert.False(result.HasError);
var model = Assert.IsType<TestLevelOne>(result.Model);
Assert.Equal(expectedInt, model.SampleInt);
Assert.Equal(expectedString, model.sampleString);
Assert.Equal(
XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc),
model.SampleDate);
Assert.True(httpContext.Request.Body.CanSeek);
httpContext.Request.Body.Seek(0L, SeekOrigin.Begin);
result = await formatter.ReadAsync(context);
// Assert
Assert.NotNull(result);
Assert.False(result.HasError);
model = Assert.IsType<TestLevelOne>(result.Model);
Assert.Equal(expectedInt, model.SampleInt);
Assert.Equal(expectedString, model.sampleString);
Assert.Equal(
XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc),
model.SampleDate);
}
[Fact]
public async Task SuppressInputFormatterBufferingSetToTrue_DoesNotBufferRequestBody_ObsoleteParameter()
{
// Arrange
var expectedInt = 10;
var expectedString = "TestString";
var expectedDateTime = XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc);
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString>" +
"<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>";
#pragma warning disable CS0618
var formatter = new XmlSerializerInputFormatter(suppressInputFormatterBuffering: true);
#pragma warning restore CS0618
var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
httpContext.Request.Body = new NonSeekableReadStream(contentBytes);
httpContext.Request.ContentType = "application/xml";
var context = GetInputFormatterContext(httpContext, typeof(TestLevelOne));
// Act
var result = await formatter.ReadAsync(context);
// Assert
Assert.NotNull(result);
Assert.False(result.HasError);
var model = Assert.IsType<TestLevelOne>(result.Model);
Assert.Equal(expectedInt, model.SampleInt);
Assert.Equal(expectedString, model.sampleString);
Assert.Equal(
XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc),
model.SampleDate);
// Reading again should fail as buffering request body is disabled
await Assert.ThrowsAsync<XmlException>(() => formatter.ReadAsync(context));
}
[Fact]
public async Task BuffersRequestBody_ByDefaultUsingMvcOptions()
{
// Arrange
var expectedInt = 10;
var expectedString = "TestString";
var expectedDateTime = XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc);
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString>" +
"<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>";
var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext(); var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature()); httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
@ -101,11 +198,11 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var expectedDateTime = XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc); var expectedDateTime = XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc);
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" + "<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString>" + "<sampleString>" + expectedString + "</sampleString>" +
"<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>"; "<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>";
var formatter = new XmlSerializerInputFormatter(suppressInputFormatterBuffering: true); var formatter = new XmlSerializerInputFormatter(new MvcOptions() { SuppressInputFormatterBuffering = true });
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext(); var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature()); httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
@ -131,6 +228,50 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
await Assert.ThrowsAsync<XmlException>(() => formatter.ReadAsync(context)); await Assert.ThrowsAsync<XmlException>(() => formatter.ReadAsync(context));
} }
[Fact]
public async Task SuppressInputFormatterBufferingSetToTrue_UsingMutatedOptions()
{
// Arrange
var expectedInt = 10;
var expectedString = "TestString";
var expectedDateTime = XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc);
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<TestLevelOne><SampleInt>" + expectedInt + "</SampleInt>" +
"<sampleString>" + expectedString + "</sampleString>" +
"<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>";
var mvcOptions = new MvcOptions();
mvcOptions.SuppressInputFormatterBuffering = false;
var formatter = new XmlSerializerInputFormatter(mvcOptions);
var contentBytes = Encoding.UTF8.GetBytes(input);
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
httpContext.Request.Body = new NonSeekableReadStream(contentBytes);
httpContext.Request.ContentType = "application/xml";
var context = GetInputFormatterContext(httpContext, typeof(TestLevelOne));
// Act
// Mutate options after passing into the constructor to make sure that the value type is not store in the constructor
mvcOptions.SuppressInputFormatterBuffering = true;
var result = await formatter.ReadAsync(context);
// Assert
Assert.NotNull(result);
Assert.False(result.HasError);
var model = Assert.IsType<TestLevelOne>(result.Model);
Assert.Equal(expectedInt, model.SampleInt);
Assert.Equal(expectedString, model.sampleString);
Assert.Equal(
XmlConvert.ToDateTime(expectedDateTime, XmlDateTimeSerializationMode.Utc),
model.SampleDate);
// Reading again should fail as buffering request body is disabled
await Assert.ThrowsAsync<XmlException>(() => formatter.ReadAsync(context));
}
[Theory] [Theory]
[InlineData("application/xml", true)] [InlineData("application/xml", true)]
[InlineData("application/*", false)] [InlineData("application/*", false)]
@ -150,7 +291,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentType, bool expectedCanRead) public void CanRead_ReturnsTrueForAnySupportedContentType(string requestContentType, bool expectedCanRead)
{ {
// Arrange // Arrange
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes("content"); var contentBytes = Encoding.UTF8.GetBytes("content");
var modelState = new ModelStateDictionary(); var modelState = new ModelStateDictionary();
@ -178,7 +319,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
public void CanRead_ReturnsFalse_ForAnyUnsupportedModelType(Type modelType, bool expectedCanRead) public void CanRead_ReturnsFalse_ForAnyUnsupportedModelType(Type modelType, bool expectedCanRead)
{ {
// Arrange // Arrange
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes("content"); var contentBytes = Encoding.UTF8.GetBytes("content");
var context = GetInputFormatterContext(contentBytes, modelType); var context = GetInputFormatterContext(contentBytes, modelType);
@ -212,7 +353,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
public void HasProperSuppportedMediaTypes() public void HasProperSuppportedMediaTypes()
{ {
// Arrange & Act // Arrange & Act
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
// Assert // Assert
Assert.Contains("application/xml", formatter.SupportedMediaTypes Assert.Contains("application/xml", formatter.SupportedMediaTypes
@ -225,7 +366,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
public void HasProperSuppportedEncodings() public void HasProperSuppportedEncodings()
{ {
// Arrange & Act // Arrange & Act
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
// Assert // Assert
Assert.Contains(formatter.SupportedEncodings, i => i.WebName == "utf-8"); Assert.Contains(formatter.SupportedEncodings, i => i.WebName == "utf-8");
@ -245,7 +386,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
"<sampleString>" + expectedString + "</sampleString>" + "<sampleString>" + expectedString + "</sampleString>" +
"<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>"; "<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>";
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelOne)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelOne));
@ -279,7 +420,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
"<sampleString>" + expectedString + "</sampleString>" + "<sampleString>" + expectedString + "</sampleString>" +
"<SampleDate>" + expectedDateTime + "</SampleDate></TestOne></TestLevelTwo>"; "<SampleDate>" + expectedDateTime + "</SampleDate></TestOne></TestLevelTwo>";
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
@ -307,7 +448,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<DummyClass><SampleInt>" + expectedInt + "</SampleInt></DummyClass>"; "<DummyClass><SampleInt>" + expectedInt + "</SampleInt></DummyClass>";
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
formatter.MaxDepth = 10; formatter.MaxDepth = 10;
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass)); var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
@ -334,7 +475,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
"<sampleString>test</sampleString>" + "<sampleString>test</sampleString>" +
"<SampleDate>" + XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) "<SampleDate>" + XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc)
+ "</SampleDate></TestOne></TestLevelTwo>"; + "</SampleDate></TestOne></TestLevelTwo>";
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
formatter.MaxDepth = 1; formatter.MaxDepth = 1;
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
@ -355,7 +496,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
"<sampleString>test</sampleString>" + "<sampleString>test</sampleString>" +
"<SampleDate>" + XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) "<SampleDate>" + XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc)
+ "</SampleDate></TestOne></TestLevelTwo>"; + "</SampleDate></TestOne></TestLevelTwo>";
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
formatter.XmlDictionaryReaderQuotas.MaxStringContentLength = 10; formatter.XmlDictionaryReaderQuotas.MaxStringContentLength = 10;
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
@ -368,7 +509,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
public void SetMaxDepth_ThrowsWhenMaxDepthIsBelowOne() public void SetMaxDepth_ThrowsWhenMaxDepthIsBelowOne()
{ {
// Arrange // Arrange
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
// Act & Assert // Act & Assert
Assert.Throws<ArgumentException>(() => formatter.MaxDepth = 0); Assert.Throws<ArgumentException>(() => formatter.MaxDepth = 0);
@ -380,7 +521,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
// Arrange // Arrange
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<DummyClass><SampleInt>10</SampleInt></DummyClass>"; "<DummyClass><SampleInt>10</SampleInt></DummyClass>";
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.UTF8.GetBytes(input); var contentBytes = Encoding.UTF8.GetBytes(input);
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass)); var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
@ -412,7 +553,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
Buffer.BlockCopy(inp, 0, contentBytes, inpStart.Length, inp.Length); Buffer.BlockCopy(inp, 0, contentBytes, inpStart.Length, inp.Length);
Buffer.BlockCopy(inpEnd, 0, contentBytes, inpStart.Length + inp.Length, inpEnd.Length); Buffer.BlockCopy(inpEnd, 0, contentBytes, inpStart.Length + inp.Length, inpEnd.Length);
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
// Act and Assert // Act and Assert
@ -431,7 +572,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
var inputBytes = Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + var inputBytes = Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<DummyClass><SampleInt>1000</SampleInt></DummyClass>"); "<DummyClass><SampleInt>1000</SampleInt></DummyClass>");
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var modelState = new ModelStateDictionary(); var modelState = new ModelStateDictionary();
var httpContext = GetHttpContext(inputBytes, contentType: "application/xml; charset=utf-16"); var httpContext = GetHttpContext(inputBytes, contentType: "application/xml; charset=utf-16");
@ -467,7 +608,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
Buffer.BlockCopy(bom, 0, contentBytes, inputStart.Length, bom.Length); Buffer.BlockCopy(bom, 0, contentBytes, inputStart.Length, bom.Length);
Buffer.BlockCopy(inputEnd, 0, contentBytes, inputStart.Length + bom.Length, inputEnd.Length); Buffer.BlockCopy(inputEnd, 0, contentBytes, inputStart.Length + bom.Length, inputEnd.Length);
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo));
// Act // Act
@ -495,7 +636,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
"<sampleString>" + expectedString + "</sampleString>" + "<sampleString>" + expectedString + "</sampleString>" +
"<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>"; "<SampleDate>" + expectedDateTime + "</SampleDate></TestLevelOne>";
var formatter = new XmlSerializerInputFormatter(); var formatter = new XmlSerializerInputFormatter(new MvcOptions());
var contentBytes = Encoding.Unicode.GetBytes(input); var contentBytes = Encoding.Unicode.GetBytes(input);
var modelState = new ModelStateDictionary(); var modelState = new ModelStateDictionary();
@ -560,6 +701,11 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml
{ {
public int createSerializerCalledCount = 0; public int createSerializerCalledCount = 0;
public TestXmlSerializerInputFormatter()
: base(new MvcOptions())
{
}
protected override XmlSerializer CreateSerializer(Type type) protected override XmlSerializer CreateSerializer(Type type)
{ {
createSerializerCalledCount++; createSerializerCalledCount++;

View File

@ -30,7 +30,7 @@ namespace XmlFormattersWebSite
// request information (Ex: Accept header). // request information (Ex: Accept header).
// So here we instead clear out the default supported media types and create new // So here we instead clear out the default supported media types and create new
// ones which are distinguishable between formatters. // ones which are distinguishable between formatters.
var xmlSerializerInputFormatter = new XmlSerializerInputFormatter(); var xmlSerializerInputFormatter = new XmlSerializerInputFormatter(new MvcOptions());
xmlSerializerInputFormatter.SupportedMediaTypes.Clear(); xmlSerializerInputFormatter.SupportedMediaTypes.Clear();
xmlSerializerInputFormatter.SupportedMediaTypes.Add( xmlSerializerInputFormatter.SupportedMediaTypes.Add(
new MediaTypeHeaderValue("application/xml-xmlser")); new MediaTypeHeaderValue("application/xml-xmlser"));
@ -44,7 +44,7 @@ namespace XmlFormattersWebSite
xmlSerializerOutputFormatter.SupportedMediaTypes.Add( xmlSerializerOutputFormatter.SupportedMediaTypes.Add(
new MediaTypeHeaderValue("text/xml-xmlser")); new MediaTypeHeaderValue("text/xml-xmlser"));
var dcsInputFormatter = new XmlDataContractSerializerInputFormatter(); var dcsInputFormatter = new XmlDataContractSerializerInputFormatter(new MvcOptions());
dcsInputFormatter.SupportedMediaTypes.Clear(); dcsInputFormatter.SupportedMediaTypes.Clear();
dcsInputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml-dcs")); dcsInputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml-dcs"));
dcsInputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml-dcs")); dcsInputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml-dcs"));