ASP.NET WebApi – Breaking change to MediaTypeFormatters

In my preview post, I described an implementation that would allow multipart/form-data image uploads to be binded to an ImageMedia model by implementing the MediaTypeFormatter. That post was based on the beta api and has since been changed a few times.

In the previous post, the method signature for ReadFromStreamAsync was:

        protected async override Task OnReadFromStreamAsync(
            Type type, Stream stream, HttpContentHeaders contentHeaders,
            FormatterContext formatterContext)

This allowed us to get at the request via the FormatterContext like this:

            HttpRequestMessage request = formatterContext.Request;

A change was then made that meant we could no longer access the HttpRequestMessage, and therefore no longer access the HttpContent property of the request.

Essentially, this change removed the FormatterContext parameter, and in its place passed an IFormatterLogger:

        public async override Task ReadFromStreamAsync(
            Type type, Stream stream, HttpContentHeaders contentHeaders,
            IFormatterLogger formatterLogger)

On the 15 August 2012, the ASP.NET WebApi was Released , and with it came a welcome change.

The team decided to replace the HttpContentHeaders parameter with the HttpContent allowing access to all the extension methods that come with it. The implementation I provided, depended on ReadAsMultipartAsync.

This method itself has also changed, as it no longer returns a collection of HttpContent, and now returns MultipartMemoryStreamProvider . The provider then allows access to the HttpContent collection via the Contents parameter.

Phew! So after all that, we can now have our ImageMediaTypeFormatter extract our image stream once again.

Enough of the pleasantries, here’s the updated ReadFromStreamAsync implementation.

        public async override Task<object> ReadFromStreamAsync(
                Type type, Stream stream, HttpContent content,
                IFormatterLogger formatterLogger)
            if (!content.IsMimeMultipartContent())
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

            var provider = await content.ReadAsMultipartAsync();

            var mediacontent = provider.Contents.First(x =>

            string fileName = mediacontent.Headers.ContentDisposition.FileName;
            string mediaType = mediacontent.Headers.ContentType.MediaType;

            using (var imgstream = await mediacontent.ReadAsStreamAsync())
                byte[] imagebuffer = imgstream.ReadFully();
                return new ImageMedia(fileName, mediaType, imagebuffer);