// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace System.Net.Http
{
///
/// Extension methods to allow strongly typed objects to be read from instances.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public static class HttpContentExtensions
{
///
/// Returns a that will yield an object of the specified
/// from the instance.
///
/// This override use the built-in collection of formatters.
/// The instance from which to read.
/// The type of the object to read.
/// A that will yield an object instance of the specified type.
public static Task ReadAsAsync(this HttpContent content, Type type)
{
return content.ReadAsAsync(type, new MediaTypeFormatterCollection());
}
///
/// Returns a that will yield an object of the specified
/// from the instance using one of the provided
/// to deserialize the content.
///
/// The instance from which to read.
/// The type of the object to read.
/// The collection of instances to use.
/// An object instance of the specified type.
public static Task ReadAsAsync(this HttpContent content, Type type, IEnumerable formatters)
{
return ReadAsAsync(content, type, formatters, null);
}
///
/// Returns a that will yield an object of the specified
/// from the instance using one of the provided
/// to deserialize the content.
///
/// The instance from which to read.
/// The type of the object to read.
/// The collection of instances to use.
/// The to log events to.
/// An object instance of the specified type.
public static Task ReadAsAsync(this HttpContent content, Type type, IEnumerable formatters, IFormatterLogger formatterLogger)
{
return ReadAsAsync(content, type, formatters, formatterLogger);
}
///
/// Returns a that will yield an object of the specified
/// type from the instance.
///
/// This override use the built-in collection of formatters.
/// The type of the object to read.
/// The instance from which to read.
/// An object instance of the specified type.
public static Task ReadAsAsync(this HttpContent content)
{
return content.ReadAsAsync(new MediaTypeFormatterCollection());
}
///
/// Returns a that will yield an object of the specified
/// type from the instance.
///
/// The type of the object to read.
/// The instance from which to read.
/// The collection of instances to use.
/// An object instance of the specified type.
public static Task ReadAsAsync(this HttpContent content, IEnumerable formatters)
{
return ReadAsAsync(content, typeof(T), formatters, null);
}
///
/// Returns a that will yield an object of the specified
/// type from the instance.
///
/// The type of the object to read.
/// The instance from which to read.
/// The collection of instances to use.
/// The to log events to.
/// An object instance of the specified type.
public static Task ReadAsAsync(this HttpContent content, IEnumerable formatters, IFormatterLogger formatterLogger)
{
return ReadAsAsync(content, typeof(T), formatters, formatterLogger);
}
// There are many helper overloads for ReadAs*(). Provide one worker function to ensure the logic is shared.
//
// For loosely typed, T = Object, type = specific class.
// For strongly typed, T == type.GetType()
private static Task ReadAsAsync(HttpContent content, Type type, IEnumerable formatters, IFormatterLogger formatterLogger)
{
if (content == null)
{
throw new ArgumentNullException("content");
}
if (type == null)
{
throw new ArgumentNullException("type");
}
if (formatters == null)
{
throw new ArgumentNullException("formatters");
}
ObjectContent objectContent = content as ObjectContent;
if (objectContent != null && objectContent.Value != null && type.IsAssignableFrom(objectContent.Value.GetType()))
{
return TaskHelpers.FromResult((T)objectContent.Value);
}
MediaTypeFormatter formatter = null;
MediaTypeHeaderValue mediaType = content.Headers.ContentType;
if (mediaType != null)
{
formatter = new MediaTypeFormatterCollection(formatters).FindReader(type, mediaType);
}
if (formatter == null)
{
string mediaTypeAsString = mediaType != null ? mediaType.MediaType : Properties.Resources.UndefinedMediaType;
throw new InvalidOperationException(
RS.Format(Properties.Resources.NoReadSerializerAvailable, type.Name, mediaTypeAsString));
}
return content.ReadAsStreamAsync()
.Then(stream => formatter.ReadFromStreamAsync(type, stream, content.Headers, formatterLogger)
.Then(value => (T)value));
}
}
}