Here’s a few more updates coming your way in ASP.NET Web API. As in the previous update the code has been checked into our CodePlex source code repository but hasn’t yet been released as part of our official installer. Think of this as a sneak-peak for you to try out and comment on as part of our source code repository (see Getting Started With ASP.NET Web Stack Source on CodePlex for details).
Helper for Wiring up Message Handlers
HttpMessageHandlers are pluggable “filters” that sit between HttpClient and the network and allow you to modify the request and/or response as they travel from a HttpClient to the network and back (see Mike Wasson’s blog on message handlers for a detailed walkthrough). HttpMessageHandlers are plugged together in a “Russian doll” model where each handler delegates to the inner handler until the last one hits the network (or a previous one short-circuited the path). The model can be illustrated like this:
This commit provides a simple HttpClientFactory that can wire up DelegatingHandlers and create an HttpClient with the desired pipeline ready to go. It also provides functionality for wiring up with alternative inner handlers (the default is HttpClientHandler) as well as do the wiring up when using HttpMessageInvoker or another DelegatingHandler instead of HttpClient as the top-invoker.
To demonstrate this we first create a handler where we override the SendAsync method to intercept the request and response path:
Then we use this handler in a sample where we instantiate three instances and wire them together:
When running this sample we get the following output on the console (note the order with A being first on request and last on response, etc.):
Being able to get progress notifications on data being uploaded and downloaded was a popular request on the beta bits which we didn’t support directly. This commit defines a ProgressMessageHandler which generates progress notification for both request entities being uploaded and response entities being downloaded. Using this handler it is possible to keep track of how far you are uploading a request body or downloading a response body.
The ProgressMessageHandler exposes two events, one for tracking upload and download progress respectively. Each progress notification is associated with a specific request so it is possible to track progress notifications from multiple ongoing requests at the same time. A sample receive progress event handler looks like this:
The send progress event handler looks exactly the same – it also receives a HttpProgressEventArgs instance with the exact same shape. Below is a sample which uses the HttpClientFactory to create an HttpClient with progress notifications hooked in:
A sample output written to the console looks like this:
Support for reading MIME multipart messages as handled by the HttpContent.ReadAsMultipartAsync extension methods had two usability problems in the original design:
- The result was IEnumerable<HttpContent> which is too low-level to facilitate easy consumption. For example, it doesn't allow for converting multipart html form data into NameValueCollection data or for any other higher-level abstraction on top of the raw IEnumerable<HttpContent>.
- The stream provider doesn't enable any post processing of the data such as converting the read data into another format before the read task completed.
This made it hard to provide a higher-level abstraction on top of IEnumerable<HttpContent> as the MultipartStreamProvider does not know when the message has been completely read.
This commit fixes these short comings by first changing the signature of the ReadAsMultipartAsync to
- public static Task<T> ReadAsMultipartAsync<T>(this HttpContent content, T streamProvider) where T : MultipartStreamProvider
This means that it is now possible to write a MultipartStreamProvider that is completely tailored to the type of MIME multipart that it can read and present the result in the optimal way to the user.
Second, we introduce a “post processing” step as part of the MultipartStreamProvider that allows the implementation to do whatever post processing it wants on the MIME multipart body parts. For example, the MultipartFormDataStreamProvider implementation reads the HTML form data parts and adds them to a NameValueCollection so they are easy to get at from the caller.
The built-in set of MultipartStreamProvider consists of:
- MultipartMemoryStreamProvider saves all MIME body parts in memory allowing them to be read, deserialized, etc.
- MultipartFileStreamProvider saves all MIME body parts as individual files.
- MultipartFormDataStreamProvider saves all form data parts in a NameValueCollection and all file parts to file. This allows the form data to be easily manipulated and files to be persisted.
- MultipartRelatedStreamProvider parses multipart related entities as defined by RFC 2387 “The MIME Multipart/Related Content-type”.
An example of how to implement an Action that handles file uploads with parameters using MultipartFormDataStreamProvider looks like this: