// 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)); } } }