Added CanReadType to InputFormatter
This commit is contained in:
parent
bb31e2aec5
commit
d236d4ffde
|
|
@ -43,6 +43,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual bool CanRead(InputFormatterContext context)
|
public virtual bool CanRead(InputFormatterContext context)
|
||||||
{
|
{
|
||||||
|
if (!CanReadType(context.ModelType))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var contentType = context.ActionContext.HttpContext.Request.ContentType;
|
var contentType = context.ActionContext.HttpContext.Request.ContentType;
|
||||||
MediaTypeHeaderValue requestContentType;
|
MediaTypeHeaderValue requestContentType;
|
||||||
if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType))
|
if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType))
|
||||||
|
|
@ -54,6 +59,16 @@ namespace Microsoft.AspNet.Mvc
|
||||||
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
|
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether or not the given type can be read by this serializer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The type of object that will be read.</param>
|
||||||
|
/// <returns><c>true</c> if the type can be read, otherwise <c>false</c>.</returns>
|
||||||
|
protected virtual bool CanReadType(Type type)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual async Task<object> ReadAsync(InputFormatterContext context)
|
public virtual async Task<object> ReadAsync(InputFormatterContext context)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
|
@ -19,6 +20,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
public class XmlDataContractSerializerInputFormatter : InputFormatter
|
public class XmlDataContractSerializerInputFormatter : InputFormatter
|
||||||
{
|
{
|
||||||
private DataContractSerializerSettings _serializerSettings;
|
private DataContractSerializerSettings _serializerSettings;
|
||||||
|
private ConcurrentDictionary<Type, object> _serializerCache = new ConcurrentDictionary<Type, object>();
|
||||||
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
|
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -93,7 +95,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
{
|
{
|
||||||
var type = GetSerializableType(context.ModelType);
|
var type = GetSerializableType(context.ModelType);
|
||||||
|
|
||||||
var serializer = CreateSerializer(type);
|
var serializer = GetCachedSerializer(type);
|
||||||
|
|
||||||
var deserializedObject = serializer.ReadObject(xmlReader);
|
var deserializedObject = serializer.ReadObject(xmlReader);
|
||||||
|
|
||||||
|
|
@ -111,6 +113,12 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override bool CanReadType([NotNull] Type type)
|
||||||
|
{
|
||||||
|
return GetCachedSerializer(GetSerializableType(type)) != null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called during deserialization to get the <see cref="XmlReader"/>.
|
/// Called during deserialization to get the <see cref="XmlReader"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -142,7 +150,36 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
/// <returns>The <see cref="DataContractSerializer"/> used during deserialization.</returns>
|
/// <returns>The <see cref="DataContractSerializer"/> used during deserialization.</returns>
|
||||||
protected virtual DataContractSerializer CreateSerializer([NotNull] Type type)
|
protected virtual DataContractSerializer CreateSerializer([NotNull] Type type)
|
||||||
{
|
{
|
||||||
return new DataContractSerializer(type, _serializerSettings);
|
try
|
||||||
|
{
|
||||||
|
// If the serializer does not support this type it will throw an exception.
|
||||||
|
return new DataContractSerializer(type, _serializerSettings);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// We do not surface the caught exception because if CanRead returns
|
||||||
|
// false, then this Formatter is not picked up at all.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the cached serializer or creates and caches the serializer for the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The <see cref="DataContractSerializer"/> instance.</returns>
|
||||||
|
protected virtual DataContractSerializer GetCachedSerializer(Type type)
|
||||||
|
{
|
||||||
|
object serializer;
|
||||||
|
if (!_serializerCache.TryGetValue(type, out serializer))
|
||||||
|
{
|
||||||
|
serializer = CreateSerializer(type);
|
||||||
|
if (serializer != null)
|
||||||
|
{
|
||||||
|
_serializerCache.TryAdd(type, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (DataContractSerializer)serializer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
|
@ -19,6 +20,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
public class XmlDataContractSerializerOutputFormatter : OutputFormatter
|
public class XmlDataContractSerializerOutputFormatter : OutputFormatter
|
||||||
{
|
{
|
||||||
private DataContractSerializerSettings _serializerSettings;
|
private DataContractSerializerSettings _serializerSettings;
|
||||||
|
private ConcurrentDictionary<Type, object> _serializerCache = new ConcurrentDictionary<Type, object>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of <see cref="XmlDataContractSerializerOutputFormatter"/>
|
/// Initializes a new instance of <see cref="XmlDataContractSerializerOutputFormatter"/>
|
||||||
|
|
@ -115,8 +117,12 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
protected override bool CanWriteType(Type declaredType, Type runtimeType)
|
protected override bool CanWriteType(Type declaredType, Type runtimeType)
|
||||||
{
|
{
|
||||||
var type = ResolveType(declaredType, runtimeType);
|
var type = ResolveType(declaredType, runtimeType);
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return CreateSerializer(GetSerializableType(type)) != null;
|
return GetCachedSerializer(GetSerializableType(type)) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -183,11 +189,30 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
obj = wrapperProvider.Wrap(obj);
|
obj = wrapperProvider.Wrap(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dataContractSerializer = CreateSerializer(wrappingType);
|
var dataContractSerializer = GetCachedSerializer(wrappingType);
|
||||||
dataContractSerializer.WriteObject(xmlWriter, obj);
|
dataContractSerializer.WriteObject(xmlWriter, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the cached serializer or creates and caches the serializer for the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The <see cref="DataContractSerializer"/> instance.</returns>
|
||||||
|
protected virtual DataContractSerializer GetCachedSerializer(Type type)
|
||||||
|
{
|
||||||
|
object serializer;
|
||||||
|
if (!_serializerCache.TryGetValue(type, out serializer))
|
||||||
|
{
|
||||||
|
serializer = CreateSerializer(type);
|
||||||
|
if (serializer != null)
|
||||||
|
{
|
||||||
|
_serializerCache.TryAdd(type, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (DataContractSerializer)serializer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -18,6 +19,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class XmlSerializerInputFormatter : InputFormatter
|
public class XmlSerializerInputFormatter : InputFormatter
|
||||||
{
|
{
|
||||||
|
private ConcurrentDictionary<Type, object> _serializerCache = new ConcurrentDictionary<Type, object>();
|
||||||
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
|
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -72,7 +74,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
{
|
{
|
||||||
var type = GetSerializableType(context.ModelType);
|
var type = GetSerializableType(context.ModelType);
|
||||||
|
|
||||||
var serializer = CreateSerializer(type);
|
var serializer = GetCachedSerializer(type);
|
||||||
|
|
||||||
var deserializedObject = serializer.Deserialize(xmlReader);
|
var deserializedObject = serializer.Deserialize(xmlReader);
|
||||||
|
|
||||||
|
|
@ -90,6 +92,12 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override bool CanReadType([NotNull] Type type)
|
||||||
|
{
|
||||||
|
return GetCachedSerializer(GetSerializableType(type)) != null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type to which the XML will be deserialized.
|
/// Gets the type to which the XML will be deserialized.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -120,7 +128,36 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
/// <returns>The <see cref="XmlSerializer"/> used during deserialization.</returns>
|
/// <returns>The <see cref="XmlSerializer"/> used during deserialization.</returns>
|
||||||
protected virtual XmlSerializer CreateSerializer(Type type)
|
protected virtual XmlSerializer CreateSerializer(Type type)
|
||||||
{
|
{
|
||||||
return new XmlSerializer(type);
|
try
|
||||||
|
{
|
||||||
|
// If the serializer does not support this type it will throw an exception.
|
||||||
|
return new XmlSerializer(type);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// We do not surface the caught exception because if CanRead returns
|
||||||
|
// false, then this Formatter is not picked up at all.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the cached serializer or creates and caches the serializer for the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The <see cref="XmlSerializer"/> instance.</returns>
|
||||||
|
protected virtual XmlSerializer GetCachedSerializer(Type type)
|
||||||
|
{
|
||||||
|
object serializer;
|
||||||
|
if (!_serializerCache.TryGetValue(type, out serializer))
|
||||||
|
{
|
||||||
|
serializer = CreateSerializer(type);
|
||||||
|
if (serializer != null)
|
||||||
|
{
|
||||||
|
_serializerCache.TryAdd(type, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (XmlSerializer) serializer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -18,6 +19,8 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class XmlSerializerOutputFormatter : OutputFormatter
|
public class XmlSerializerOutputFormatter : OutputFormatter
|
||||||
{
|
{
|
||||||
|
private ConcurrentDictionary<Type, object> _serializerCache = new ConcurrentDictionary<Type, object>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of <see cref="XmlSerializerOutputFormatter"/>
|
/// Initializes a new instance of <see cref="XmlSerializerOutputFormatter"/>
|
||||||
/// with default XmlWriterSettings.
|
/// with default XmlWriterSettings.
|
||||||
|
|
@ -93,8 +96,12 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
protected override bool CanWriteType(Type declaredType, Type runtimeType)
|
protected override bool CanWriteType(Type declaredType, Type runtimeType)
|
||||||
{
|
{
|
||||||
var type = ResolveType(declaredType, runtimeType);
|
var type = ResolveType(declaredType, runtimeType);
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return CreateSerializer(GetSerializableType(type)) != null;
|
return GetCachedSerializer(GetSerializableType(type)) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -159,11 +166,30 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
obj = wrapperProvider.Wrap(obj);
|
obj = wrapperProvider.Wrap(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
var xmlSerializer = CreateSerializer(wrappingType);
|
var xmlSerializer = GetCachedSerializer(wrappingType);
|
||||||
xmlSerializer.Serialize(xmlWriter, obj);
|
xmlSerializer.Serialize(xmlWriter, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the cached serializer or creates and caches the serializer for the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The <see cref="XmlSerializer"/> instance.</returns>
|
||||||
|
protected virtual XmlSerializer GetCachedSerializer(Type type)
|
||||||
|
{
|
||||||
|
object serializer;
|
||||||
|
if (!_serializerCache.TryGetValue(type, out serializer))
|
||||||
|
{
|
||||||
|
serializer = CreateSerializer(type);
|
||||||
|
if (serializer != null)
|
||||||
|
{
|
||||||
|
_serializerCache.TryAdd(type, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (XmlSerializer)serializer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -10,7 +10,6 @@ using System.Threading.Tasks;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Xml;
|
|
||||||
using Microsoft.AspNet.Testing;
|
using Microsoft.AspNet.Testing;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -79,6 +78,24 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
Assert.Equal(expectedCanRead, result);
|
Assert.Equal(expectedCanRead, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void XmlDataContractSerializer_CachesSerializerForType()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||||
|
"<DummyClass><SampleInt>10</SampleInt></DummyClass>";
|
||||||
|
var formatter = new TestXmlDataContractSerializerInputFormatter();
|
||||||
|
var contentBytes = Encoding.UTF8.GetBytes(input);
|
||||||
|
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
formatter.CanRead(context);
|
||||||
|
formatter.CanRead(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(1, formatter.createSerializerCalledCount);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HasProperSuppportedMediaTypes()
|
public void HasProperSuppportedMediaTypes()
|
||||||
{
|
{
|
||||||
|
|
@ -485,5 +502,16 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
||||||
return httpContext.Object;
|
return httpContext.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestXmlDataContractSerializerInputFormatter : XmlDataContractSerializerInputFormatter
|
||||||
|
{
|
||||||
|
public int createSerializerCalledCount = 0;
|
||||||
|
|
||||||
|
protected override DataContractSerializer CreateSerializer(Type type)
|
||||||
|
{
|
||||||
|
createSerializerCalledCount++;
|
||||||
|
return base.CreateSerializer(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -111,6 +111,22 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead);
|
Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void XmlDataContractSerializer_CachesSerializerForType()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var input = new DummyClass { SampleInt = 10 };
|
||||||
|
var formatter = new TestXmlDataContractSerializerOutputFormatter();
|
||||||
|
var context = GetOutputFormatterContext(input, typeof(DummyClass));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
formatter.CanWriteResult(context, MediaTypeHeaderValue.Parse("application/xml"));
|
||||||
|
formatter.CanWriteResult(context, MediaTypeHeaderValue.Parse("application/xml"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(1, formatter.createSerializerCalledCount);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void DefaultConstructor_ExpectedWriterSettings_Created()
|
public void DefaultConstructor_ExpectedWriterSettings_Created()
|
||||||
{
|
{
|
||||||
|
|
@ -552,5 +568,16 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
httpContext.SetupGet(c => c.Response).Returns(response.Object);
|
httpContext.SetupGet(c => c.Response).Returns(response.Object);
|
||||||
return new ActionContext(httpContext.Object, routeData: null, actionDescriptor: null);
|
return new ActionContext(httpContext.Object, routeData: null, actionDescriptor: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestXmlDataContractSerializerOutputFormatter : XmlDataContractSerializerOutputFormatter
|
||||||
|
{
|
||||||
|
public int createSerializerCalledCount = 0;
|
||||||
|
|
||||||
|
protected override DataContractSerializer CreateSerializer(Type type)
|
||||||
|
{
|
||||||
|
createSerializerCalledCount++;
|
||||||
|
return base.CreateSerializer(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
#if ASPNET50
|
#if ASPNET50
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Xml;
|
using Microsoft.AspNet.Mvc.Xml;
|
||||||
|
|
@ -64,6 +66,42 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
Assert.Equal(expectedCanRead, result);
|
Assert.Equal(expectedCanRead, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(typeof(Dictionary<string, object>), false)]
|
||||||
|
[InlineData(typeof(string), true)]
|
||||||
|
public void CanRead_ReturnsFalse_ForAnyUnsupportedModelType(Type modelType, bool expectedCanRead)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var formatter = new XmlSerializerInputFormatter();
|
||||||
|
var contentBytes = Encoding.UTF8.GetBytes("content");
|
||||||
|
|
||||||
|
var context = GetInputFormatterContext(contentBytes, modelType);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = formatter.CanRead(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedCanRead, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void XmlSerializer_CachesSerializerForType()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||||
|
"<DummyClass><SampleInt>10</SampleInt></DummyClass>";
|
||||||
|
var formatter = new TestXmlSerializerInputFormatter();
|
||||||
|
var contentBytes = Encoding.UTF8.GetBytes(input);
|
||||||
|
var context = GetInputFormatterContext(contentBytes, typeof(DummyClass));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
formatter.CanRead(context);
|
||||||
|
formatter.CanRead(context);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(1, formatter.createSerializerCalledCount);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HasProperSuppportedMediaTypes()
|
public void HasProperSuppportedMediaTypes()
|
||||||
{
|
{
|
||||||
|
|
@ -374,6 +412,17 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
httpContext.SetupGet(c => c.Request).Returns(request.Object);
|
||||||
return httpContext.Object;
|
return httpContext.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestXmlSerializerInputFormatter : XmlSerializerInputFormatter
|
||||||
|
{
|
||||||
|
public int createSerializerCalledCount = 0;
|
||||||
|
|
||||||
|
protected override XmlSerializer CreateSerializer(Type type)
|
||||||
|
{
|
||||||
|
createSerializerCalledCount++;
|
||||||
|
return base.CreateSerializer(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ using Microsoft.Net.Http.Headers;
|
||||||
using Microsoft.AspNet.Mvc.Xml;
|
using Microsoft.AspNet.Mvc.Xml;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Xml
|
namespace Microsoft.AspNet.Mvc.Xml
|
||||||
{
|
{
|
||||||
|
|
@ -68,6 +69,22 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead);
|
Assert.True(outputFormatterContext.ActionContext.HttpContext.Response.Body.CanRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void XmlSerializer_CachesSerializerForType()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var input = new DummyClass { SampleInt = 10 };
|
||||||
|
var formatter = new TestXmlSerializerOutputFormatter();
|
||||||
|
var context = GetOutputFormatterContext(input, typeof(DummyClass));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
formatter.CanWriteResult(context, MediaTypeHeaderValue.Parse("application/xml"));
|
||||||
|
formatter.CanWriteResult(context, MediaTypeHeaderValue.Parse("application/xml"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(1, formatter.createSerializerCalledCount);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void DefaultConstructor_ExpectedWriterSettings_Created()
|
public void DefaultConstructor_ExpectedWriterSettings_Created()
|
||||||
{
|
{
|
||||||
|
|
@ -355,5 +372,16 @@ namespace Microsoft.AspNet.Mvc.Xml
|
||||||
httpContext.SetupGet(c => c.Response).Returns(response.Object);
|
httpContext.SetupGet(c => c.Response).Returns(response.Object);
|
||||||
return new ActionContext(httpContext.Object, routeData: null, actionDescriptor: null);
|
return new ActionContext(httpContext.Object, routeData: null, actionDescriptor: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestXmlSerializerOutputFormatter : XmlSerializerOutputFormatter
|
||||||
|
{
|
||||||
|
public int createSerializerCalledCount = 0;
|
||||||
|
|
||||||
|
protected override XmlSerializer CreateSerializer(Type type)
|
||||||
|
{
|
||||||
|
createSerializerCalledCount++;
|
||||||
|
return base.CreateSerializer(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue