// 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.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
///
/// This class handles deserialization of input XML data
/// to strongly-typed objects using
///
public class XmlSerializerInputFormatter : IInputFormatter
{
private readonly XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.GetDefaultXmlReaderQuotas();
///
/// Initializes a new instance of XmlSerializerInputFormatter.
///
public XmlSerializerInputFormatter()
{
SupportedEncodings = new List();
SupportedEncodings.Add(Encodings.UTF8EncodingWithoutBOM);
SupportedEncodings.Add(Encodings.UTF16EncodingLittleEndian);
SupportedMediaTypes = new List();
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/xml"));
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/xml"));
}
///
public IList SupportedMediaTypes { get; private set; }
///
public IList SupportedEncodings { get; private set; }
///
/// Indicates the acceptable input XML depth.
///
public int MaxDepth
{
get { return _readerQuotas.MaxDepth; }
set { _readerQuotas.MaxDepth = value; }
}
///
/// The quotas include - DefaultMaxDepth, DefaultMaxStringContentLength, DefaultMaxArrayLength,
/// DefaultMaxBytesPerRead, DefaultMaxNameTableCharCount
///
public XmlDictionaryReaderQuotas XmlDictionaryReaderQuotas
{
get { return _readerQuotas; }
}
///
/// Reads the input XML.
///
/// The input formatter context which contains the body to be read.
/// Task which reads the input.
public async Task ReadAsync(InputFormatterContext context)
{
var request = context.HttpContext.Request;
if (request.ContentLength == 0)
{
context.Model = GetDefaultValueForType(context.Metadata.ModelType);
return;
}
context.Model = await ReadInternal(context);
}
///
/// Called during deserialization to get the .
///
/// The from which to read.
/// The used during deserialization.
protected virtual XmlReader CreateXmlReader([NotNull] Stream readStream)
{
return XmlDictionaryReader.CreateTextReader(
readStream, _readerQuotas);
}
///
/// Called during deserialization to get the .
///
/// The used during deserialization.
protected virtual XmlSerializer CreateXmlSerializer(Type type)
{
return new XmlSerializer(type);
}
private object GetDefaultValueForType(Type modelType)
{
if (modelType.GetTypeInfo().IsValueType)
{
return Activator.CreateInstance(modelType);
}
return null;
}
private Task