The 4.5 version of the .NET platform introduces the new System.Net.Http namespace with several HTTP related classes. These classes are also available for .NET 4.0, via the Web API Preview 6 distribution (both source code and NuGet package).
A previous post introduced the HTTP core classes (HttpRequestMessage, HttpResponseMessage and HttpMessageHandler) and described the HttpClient class in detail.
This post addresses HTTP message’s content manipulation , and is based on the Web API Preview 6 distribution. Some links point to the MSDN preliminary 4.5 documentation, while others point to the Web API Preview 6 source code; so expect discrepancies. Notice that this post is based on preview code and documentation; the final .NET 4.5 classes may be different of what is described here.
The HttpContent class
The content of both request and response messages is access via the Content property, of type HttpContent.
The HttpContent class contains a Headers property, with the content related HTTP headers (e.g. Content-Language, Content-Type, Last-Modified).
It also contains a set of ReadAsXxx methods for asynchronously accessing the content body:
- Task<Stream> ReadAsStreamAsync()
- Task<byte[]> ReadAsByteArrayAsync()
- Task<string> ReadAsStringAsync()
Creating new content
Reading the message raw content, as a byte sequence or as a string, is accomplished using one of the above methods. However, creating new content involves a hierarchy of concrete classes, rooted at the abstract HttpContent class.
Each one of those classes support a specific type of content or content source. For instance, producing a string based content is accomplished by creating a StringContent instance, parameterized with the string content, the character encoding, and the media type.
Typed Content
The System.Net.Http namespace also contains a ObjectContent class for representing strongly typed content, i.e., content based on a strongly typed object.
As depicted in the following diagram, the ObjectContent derives from HttpContent. There is also a ObjectContent<T> deriving from ObjectContent, which uses a generic parameter instead of a Type instance to represent the content’s type.
The ObjectContent is used differently when reading content or producing content.
Reading strongly typed content
When reading strongly typed content, an ObjectContent instance is created from a HttpContent and a MediaTypeFormatter is used to convert the HttpContent’s stream into the ObjectContent’s object.
The HttpContentExtensionMethods class contains extension methods to do this
For instance, the ReadAsAsync method performs the following
public static Task ReadAsAsync(this HttpContent content) { if (content == null) { throw new ArgumentNullException("content"); } return BuildObjectContent(content).ReadAsAsync(); } private static ObjectContent BuildObjectContent(HttpContent content) { ObjectContent objectContent = content as ObjectContent; if (objectContent == null) { objectContent = new ObjectContent(content); } return objectContent; }
Note that reading strongly typed content involves two contents:
- The original message content, exposed as a byte stream.
- The object content, containing an object obtained from the above stream.
Producing strongly typed content
Producing strongly typed content is simpler: just create a ObjectContent (or ObjectContent<T>) instance, passing in the object. Since, ObjectContent derives from HttpContent, this new instance can be directly used as a message content. Internally, a MediaTypeFormatter is used to convert from the typed object into a stream (e.g. when a request message is serialized “to the wire”).
Notice that the MediaTypeFormatter class is used for bidirectional conversion:
- From a byte stream into a typed object.
- From a typed object into a byte stream.
This class will be the subject of a future post.
Final remarks
- Abstract HttpContent base class for representing HTTP message content. Contains a set of methods for reading the content’s body as a byte sequence or a string.
- Concrete HttpContent-derived classes for creating content.
- ObjectContent and ObjectContent<T> classes for reading and creating HTTP message body content from strongly typed objects.