added InputFormatter base type
This commit is contained in:
parent
e1e43e1e8c
commit
13e1c9d5e1
|
|
@ -0,0 +1,105 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads an object from the request body.
|
||||
/// </summary>
|
||||
public abstract class InputFormatter : IInputFormatter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the mutable collection of character encodings supported by
|
||||
/// this <see cref="InputFormatter"/>. The encodings are
|
||||
/// used when reading the data.
|
||||
/// </summary>
|
||||
public IList<Encoding> SupportedEncodings { get; } = new List<Encoding>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mutable collection of <see cref="MediaTypeHeaderValue"/> elements supported by
|
||||
/// this <see cref="InputFormatter"/>.
|
||||
/// </summary>
|
||||
public IList<MediaTypeHeaderValue> SupportedMediaTypes { get; } = new List<MediaTypeHeaderValue>();
|
||||
|
||||
protected object GetDefaultValueForType(Type modelType)
|
||||
{
|
||||
if (modelType.GetTypeInfo().IsValueType)
|
||||
{
|
||||
return Activator.CreateInstance(modelType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool CanRead(InputFormatterContext context)
|
||||
{
|
||||
var contentType = context.ActionContext.HttpContext.Request.ContentType;
|
||||
MediaTypeHeaderValue requestContentType;
|
||||
if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return SupportedMediaTypes
|
||||
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual async Task<object> ReadAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
if (request.ContentLength == 0)
|
||||
{
|
||||
return GetDefaultValueForType(context.ModelType);
|
||||
}
|
||||
|
||||
return await ReadRequestBodyAsync(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the request body.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="InputFormatterContext"/> associated with the call.</param>
|
||||
/// <returns>A task which can read the request body.</returns>
|
||||
public abstract Task<object> ReadRequestBodyAsync(InputFormatterContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Returns encoding based on content type charset parameter.
|
||||
/// </summary>
|
||||
protected Encoding SelectCharacterEncoding(MediaTypeHeaderValue contentType)
|
||||
{
|
||||
if (contentType != null)
|
||||
{
|
||||
var charset = contentType.Charset;
|
||||
if (!string.IsNullOrWhiteSpace(contentType.Charset))
|
||||
{
|
||||
foreach (var supportedEncoding in SupportedEncodings)
|
||||
{
|
||||
if (string.Equals(charset, supportedEncoding.WebName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return supportedEncoding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SupportedEncodings.Count > 0)
|
||||
{
|
||||
return SupportedEncodings[0];
|
||||
}
|
||||
|
||||
// No supported encoding was found so there is no way for us to start reading.
|
||||
throw new InvalidOperationException(Resources.FormatInputFormatterNoEncoding(GetType().FullName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,29 +2,24 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class JsonInputFormatter : IInputFormatter
|
||||
public class JsonInputFormatter : InputFormatter
|
||||
{
|
||||
private const int DefaultMaxDepth = 32;
|
||||
private JsonSerializerSettings _jsonSerializerSettings;
|
||||
|
||||
public JsonInputFormatter()
|
||||
{
|
||||
SupportedEncodings = new List<Encoding>();
|
||||
SupportedEncodings.Add(Encodings.UTF8EncodingWithoutBOM);
|
||||
SupportedEncodings.Add(Encodings.UTF16EncodingLittleEndian);
|
||||
SupportedMediaTypes = new List<MediaTypeHeaderValue>();
|
||||
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/json"));
|
||||
|
||||
|
|
@ -42,12 +37,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IList<MediaTypeHeaderValue> SupportedMediaTypes { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IList<Encoding> SupportedEncodings { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="JsonSerializerSettings"/> used to configure the <see cref="JsonSerializer"/>.
|
||||
/// </summary>
|
||||
|
|
@ -72,31 +61,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
public bool CaptureDeserilizationErrors { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool CanRead(InputFormatterContext context)
|
||||
{
|
||||
var contentType = context.ActionContext.HttpContext.Request.ContentType;
|
||||
MediaTypeHeaderValue requestContentType;
|
||||
if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return SupportedMediaTypes
|
||||
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<object> ReadAsync([NotNull] InputFormatterContext context)
|
||||
public override Task<object> ReadRequestBodyAsync([NotNull] InputFormatterContext context)
|
||||
{
|
||||
var type = context.ModelType;
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
if (request.ContentLength == 0)
|
||||
{
|
||||
var modelType = context.ModelType;
|
||||
var model = modelType.GetTypeInfo().IsValueType ? Activator.CreateInstance(modelType) :
|
||||
null;
|
||||
return model;
|
||||
}
|
||||
|
||||
MediaTypeHeaderValue requestContentType = null;
|
||||
MediaTypeHeaderValue.TryParse(request.ContentType, out requestContentType);
|
||||
|
||||
|
|
@ -104,38 +72,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
// Never non-null since SelectCharacterEncoding() throws in error / not found scenarios
|
||||
var effectiveEncoding = SelectCharacterEncoding(requestContentType);
|
||||
|
||||
return await ReadInternal(context, effectiveEncoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called during deserialization to get the <see cref="JsonReader"/>.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="InputFormatterContext"/> for the read.</param>
|
||||
/// <param name="readStream">The <see cref="Stream"/> from which to read.</param>
|
||||
/// <param name="effectiveEncoding">The <see cref="Encoding"/> to use when reading.</param>
|
||||
/// <returns>The <see cref="JsonReader"/> used during deserialization.</returns>
|
||||
public virtual JsonReader CreateJsonReader([NotNull] InputFormatterContext context,
|
||||
[NotNull] Stream readStream,
|
||||
[NotNull] Encoding effectiveEncoding)
|
||||
{
|
||||
return new JsonTextReader(new StreamReader(readStream, effectiveEncoding));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called during deserialization to get the <see cref="JsonSerializer"/>.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="JsonSerializer"/> used during serialization and deserialization.</returns>
|
||||
public virtual JsonSerializer CreateJsonSerializer()
|
||||
{
|
||||
return JsonSerializer.Create(SerializerSettings);
|
||||
}
|
||||
|
||||
private Task<object> ReadInternal(InputFormatterContext context,
|
||||
Encoding effectiveEncoding)
|
||||
{
|
||||
var type = context.ModelType;
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
|
||||
using (var jsonReader = CreateJsonReader(context, request.Body, effectiveEncoding))
|
||||
{
|
||||
jsonReader.CloseInput = false;
|
||||
|
|
@ -172,31 +108,27 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
private Encoding SelectCharacterEncoding(MediaTypeHeaderValue contentType)
|
||||
/// <summary>
|
||||
/// Called during deserialization to get the <see cref="JsonReader"/>.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="InputFormatterContext"/> for the read.</param>
|
||||
/// <param name="readStream">The <see cref="Stream"/> from which to read.</param>
|
||||
/// <param name="effectiveEncoding">The <see cref="Encoding"/> to use when reading.</param>
|
||||
/// <returns>The <see cref="JsonReader"/> used during deserialization.</returns>
|
||||
public virtual JsonReader CreateJsonReader([NotNull] InputFormatterContext context,
|
||||
[NotNull] Stream readStream,
|
||||
[NotNull] Encoding effectiveEncoding)
|
||||
{
|
||||
if (contentType != null)
|
||||
{
|
||||
// Find encoding based on content type charset parameter
|
||||
var charset = contentType.Charset;
|
||||
if (!string.IsNullOrWhiteSpace(contentType.Charset))
|
||||
{
|
||||
foreach (var supportedEncoding in SupportedEncodings)
|
||||
{
|
||||
if (string.Equals(charset, supportedEncoding.WebName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return supportedEncoding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new JsonTextReader(new StreamReader(readStream, effectiveEncoding));
|
||||
}
|
||||
|
||||
if (SupportedEncodings.Count > 0)
|
||||
{
|
||||
return SupportedEncodings[0];
|
||||
}
|
||||
|
||||
// No supported encoding was found so there is no way for us to start reading.
|
||||
throw new InvalidOperationException(Resources.FormatInputFormatterNoEncoding(GetType().FullName));
|
||||
/// <summary>
|
||||
/// Called during deserialization to get the <see cref="JsonSerializer"/>.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="JsonSerializer"/> used during serialization and deserialization.</returns>
|
||||
public virtual JsonSerializer CreateJsonSerializer()
|
||||
{
|
||||
return JsonSerializer.Create(SerializerSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// this <see cref="OutputFormatter"/>. The encodings are
|
||||
/// used when writing the data.
|
||||
/// </summary>
|
||||
public IList<Encoding> SupportedEncodings { get; private set; }
|
||||
public IList<Encoding> SupportedEncodings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mutable collection of <see cref="MediaTypeHeaderValue"/> elements supported by
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Microsoft.AspNet.Mvc.Internal;
|
||||
|
|
@ -19,7 +16,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// This class handles deserialization of input XML data
|
||||
/// to strongly-typed objects using <see cref="DataContractSerializer"/>.
|
||||
/// </summary>
|
||||
public class XmlDataContractSerializerInputFormatter : IInputFormatter
|
||||
public class XmlDataContractSerializerInputFormatter : InputFormatter
|
||||
{
|
||||
private DataContractSerializerSettings _serializerSettings;
|
||||
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
|
||||
|
|
@ -29,11 +26,9 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// </summary>
|
||||
public XmlDataContractSerializerInputFormatter()
|
||||
{
|
||||
SupportedEncodings = new List<Encoding>();
|
||||
SupportedEncodings.Add(Encodings.UTF8EncodingWithoutBOM);
|
||||
SupportedEncodings.Add(Encodings.UTF16EncodingLittleEndian);
|
||||
|
||||
SupportedMediaTypes = new List<MediaTypeHeaderValue>();
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/xml"));
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/xml"));
|
||||
|
||||
|
|
@ -49,12 +44,6 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// </summary>
|
||||
public IList<IWrapperProviderFactory> WrapperProviderFactories { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IList<MediaTypeHeaderValue> SupportedMediaTypes { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IList<Encoding> SupportedEncodings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the acceptable input XML depth.
|
||||
/// </summary>
|
||||
|
|
@ -73,20 +62,6 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
get { return _readerQuotas; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool CanRead(InputFormatterContext context)
|
||||
{
|
||||
var contentType = context.ActionContext.HttpContext.Request.ContentType;
|
||||
MediaTypeHeaderValue requestContentType;
|
||||
if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return SupportedMediaTypes
|
||||
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="DataContractSerializerSettings"/> used to configure the
|
||||
/// <see cref="DataContractSerializer"/>.
|
||||
|
|
@ -110,15 +85,30 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// </summary>
|
||||
/// <param name="context">The input formatter context which contains the body to be read.</param>
|
||||
/// <returns>Task which reads the input.</returns>
|
||||
public async Task<object> ReadAsync(InputFormatterContext context)
|
||||
public override Task<object> ReadRequestBodyAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
if (request.ContentLength == 0)
|
||||
{
|
||||
return GetDefaultValueForType(context.ModelType);
|
||||
}
|
||||
|
||||
return await ReadInternalAsync(context);
|
||||
using (var xmlReader = CreateXmlReader(new NonDisposableStream(request.Body)))
|
||||
{
|
||||
var type = GetSerializableType(context.ModelType);
|
||||
|
||||
var serializer = CreateSerializer(type);
|
||||
|
||||
var deserializedObject = serializer.ReadObject(xmlReader);
|
||||
|
||||
// Unwrap only if the original type was wrapped.
|
||||
if (type != context.ModelType)
|
||||
{
|
||||
var unwrappable = deserializedObject as IUnwrappable;
|
||||
if (unwrappable != null)
|
||||
{
|
||||
deserializedObject = unwrappable.Unwrap(declaredType: context.ModelType);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(deserializedObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -154,41 +144,5 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
{
|
||||
return new DataContractSerializer(type, _serializerSettings);
|
||||
}
|
||||
|
||||
private object GetDefaultValueForType(Type modelType)
|
||||
{
|
||||
if (modelType.GetTypeInfo().IsValueType)
|
||||
{
|
||||
return Activator.CreateInstance(modelType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Task<object> ReadInternalAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
|
||||
using (var xmlReader = CreateXmlReader(new NonDisposableStream(request.Body)))
|
||||
{
|
||||
var type = GetSerializableType(context.ModelType);
|
||||
|
||||
var serializer = CreateSerializer(type);
|
||||
|
||||
var deserializedObject = serializer.ReadObject(xmlReader);
|
||||
|
||||
// Unwrap only if the original type was wrapped.
|
||||
if (type != context.ModelType)
|
||||
{
|
||||
var unwrappable = deserializedObject as IUnwrappable;
|
||||
if (unwrappable != null)
|
||||
{
|
||||
deserializedObject = unwrappable.Unwrap(declaredType: context.ModelType);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(deserializedObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
|
@ -19,7 +16,7 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// This class handles deserialization of input XML data
|
||||
/// to strongly-typed objects using <see cref="XmlSerializer"/>
|
||||
/// </summary>
|
||||
public class XmlSerializerInputFormatter : IInputFormatter
|
||||
public class XmlSerializerInputFormatter : InputFormatter
|
||||
{
|
||||
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
|
||||
|
||||
|
|
@ -28,11 +25,9 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// </summary>
|
||||
public XmlSerializerInputFormatter()
|
||||
{
|
||||
SupportedEncodings = new List<Encoding>();
|
||||
SupportedEncodings.Add(Encodings.UTF8EncodingWithoutBOM);
|
||||
SupportedEncodings.Add(Encodings.UTF16EncodingLittleEndian);
|
||||
|
||||
SupportedMediaTypes = new List<MediaTypeHeaderValue>();
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/xml"));
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/xml"));
|
||||
|
||||
|
|
@ -46,12 +41,6 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
/// </summary>
|
||||
public IList<IWrapperProviderFactory> WrapperProviderFactories { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IList<MediaTypeHeaderValue> SupportedMediaTypes { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IList<Encoding> SupportedEncodings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the acceptable input XML depth.
|
||||
/// </summary>
|
||||
|
|
@ -70,34 +59,35 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
get { return _readerQuotas; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool CanRead(InputFormatterContext context)
|
||||
{
|
||||
var contentType = context.ActionContext.HttpContext.Request.ContentType;
|
||||
MediaTypeHeaderValue requestContentType;
|
||||
if (!MediaTypeHeaderValue.TryParse(contentType, out requestContentType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return SupportedMediaTypes
|
||||
.Any(supportedMediaType => supportedMediaType.IsSubsetOf(requestContentType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the input XML.
|
||||
/// </summary>
|
||||
/// <param name="context">The input formatter context which contains the body to be read.</param>
|
||||
/// <returns>Task which reads the input.</returns>
|
||||
public async Task<object> ReadAsync(InputFormatterContext context)
|
||||
public override Task<object> ReadRequestBodyAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
if (request.ContentLength == 0)
|
||||
{
|
||||
return GetDefaultValueForType(context.ModelType);
|
||||
}
|
||||
|
||||
return await ReadInternalAsync(context);
|
||||
using (var xmlReader = CreateXmlReader(new NonDisposableStream(request.Body)))
|
||||
{
|
||||
var type = GetSerializableType(context.ModelType);
|
||||
|
||||
var serializer = CreateSerializer(type);
|
||||
|
||||
var deserializedObject = serializer.Deserialize(xmlReader);
|
||||
|
||||
// Unwrap only if the original type was wrapped.
|
||||
if (type != context.ModelType)
|
||||
{
|
||||
var unwrappable = deserializedObject as IUnwrappable;
|
||||
if (unwrappable != null)
|
||||
{
|
||||
deserializedObject = unwrappable.Unwrap(declaredType: context.ModelType);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(deserializedObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -132,41 +122,5 @@ namespace Microsoft.AspNet.Mvc.Xml
|
|||
{
|
||||
return new XmlSerializer(type);
|
||||
}
|
||||
|
||||
private object GetDefaultValueForType(Type modelType)
|
||||
{
|
||||
if (modelType.GetTypeInfo().IsValueType)
|
||||
{
|
||||
return Activator.CreateInstance(modelType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Task<object> ReadInternalAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
|
||||
using (var xmlReader = CreateXmlReader(new NonDisposableStream(request.Body)))
|
||||
{
|
||||
var type = GetSerializableType(context.ModelType);
|
||||
|
||||
var serializer = CreateSerializer(type);
|
||||
|
||||
var deserializedObject = serializer.Deserialize(xmlReader);
|
||||
|
||||
// Unwrap only if the original type was wrapped.
|
||||
if (type != context.ModelType)
|
||||
{
|
||||
var unwrappable = deserializedObject as IUnwrappable;
|
||||
if (unwrappable != null)
|
||||
{
|
||||
deserializedObject = unwrappable.Unwrap(declaredType: context.ModelType);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(deserializedObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -163,5 +163,42 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal(expectedSampleIntValue.ToString(), responseBody);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("utf-8")]
|
||||
[InlineData("unicode")]
|
||||
public async Task CustomFormatter_IsSelected_ForSupportedContentTypeAndEncoding(string encoding)
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var content = new StringContent("Test Content", Encoding.GetEncoding(encoding), "text/plain");
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync("http://localhost/InputFormatter/ReturnInput/", content);
|
||||
var responseBody = await response.Content.ReadAsStringAsync();
|
||||
|
||||
//Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("Test Content", responseBody);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("image/png")]
|
||||
[InlineData("image/jpeg")]
|
||||
public async Task CustomFormatter_NotSelected_ForUnsupportedContentType(string contentType)
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_services, _app);
|
||||
var client = server.CreateClient();
|
||||
var content = new StringContent("Test Content", Encoding.UTF8, contentType);
|
||||
|
||||
// Act
|
||||
var response = await client.PostAsync("http://localhost/InputFormatter/ReturnInput/", content);
|
||||
var responseBody = await response.Content.ReadAsStringAsync();
|
||||
|
||||
//Assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.WebUtilities;
|
||||
|
||||
namespace FormatterWebSite.Controllers
|
||||
{
|
||||
|
|
@ -35,5 +36,15 @@ namespace FormatterWebSite.Controllers
|
|||
{
|
||||
return dummy;
|
||||
}
|
||||
|
||||
public IActionResult ReturnInput([FromBody] string test)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return new HttpStatusCodeResult(StatusCodes.Status400BadRequest);
|
||||
}
|
||||
|
||||
return Content(test);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ namespace FormatterWebSite
|
|||
options.ValidationExcludeFilters.Add(typeof(Supplier));
|
||||
|
||||
options.AddXmlDataContractSerializerFormatter();
|
||||
options.InputFormatters.Add(new StringInputFormatter());
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace FormatterWebSite
|
||||
{
|
||||
public class StringInputFormatter : InputFormatter
|
||||
{
|
||||
public StringInputFormatter()
|
||||
{
|
||||
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/plain"));
|
||||
|
||||
SupportedEncodings.Add(Encoding.UTF8);
|
||||
SupportedEncodings.Add(Encoding.Unicode);
|
||||
}
|
||||
|
||||
public override Task<object> ReadRequestBodyAsync(InputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
MediaTypeHeaderValue requestContentType = null;
|
||||
MediaTypeHeaderValue.TryParse(request.ContentType, out requestContentType);
|
||||
var effectiveEncoding = SelectCharacterEncoding(requestContentType);
|
||||
|
||||
using (var reader = new StreamReader(request.Body, effectiveEncoding))
|
||||
{
|
||||
var stringContent = reader.ReadToEnd();
|
||||
return Task.FromResult<object>(stringContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue