ReadAsAsync DefautlFormatters

Topics: ASP.NET Web API
Jun 4, 2012 at 8:32 PM

Should HttpContextExtensions.ReadAsAsync<T> be creating a new MediaTypeFormatterCollection() or should it be using GlobalConfiguration.Configuration.Formatters ?

Right now it just does new ( ) but then it does not pick up the Jquery formatter

Developer
Jun 4, 2012 at 9:07 PM

You would need to explicitly pass the GlobalConfiguration's formatters to ReadAsAsync().

We do not use GlobalConfiguration's formatters automatically because ReadAsAsync() extension can be used at the client side too, where we do not have any concept of Configuration.

Jun 4, 2012 at 9:13 PM

Can we find a better solution than that? The root of the problem here is that MediaTypeFormatterCollection has the wrong defaults right? Can it be changed, MediaTypeFormatterCollection be subclassed to have correct defaults?

Jun 5, 2012 at 2:20 AM
chrisortman wrote:

Can we find a better solution than that? The root of the problem here is that MediaTypeFormatterCollection has the wrong defaults right? Can it be changed, MediaTypeFormatterCollection be subclassed to have correct defaults?

Can you expand on how the ReadAsAsync method would work with a MediaTypeFormatterCollection subclass instance?

Coordinator
Jun 5, 2012 at 6:13 PM

The thing to realize here is that ReadAsAsync may be used on a client that has no knowledge of the server. Think of a Win8 Metro app talking to a remote Web API. So, ReadAsAsync can’t have any dependency on HttpConfiguration.

Daniel Roth

Jun 5, 2012 at 7:57 PM

I was thinking (maybe mistakenly now that I have looked at it  more) that by default MediaTypeFormatter collection should have an instance of JqueryMVCFormUrlEncodedFormatter instead of FormUrlEncodedMediaTypeFormatter. But now that I've looked at it I'm not so sure...

Here's what happened, I've got a project that started back when WebAPI was part of WCF and trying to keep up with the changes, so I had a lot of code that is just dealing with HttpRequestMessage and HttpResponseMessage

When I updated to the RC this started failing:

  return this.Request.Content.ReadAsAsync<LoginRequest>().ContinueWith(r =>

When I did an Ajax form submission it would throw

No MediaTypeFormatter is available to read an object of type 'LoginRequest' from content with media type 'application/x-www-form-urlencoded'.

I wound up figuring out that the JqueryMVCFormUrlEncodedFormatter could handle this but not FormUrlEncodedMediaTypeFormatter so went digging trying to figure out why it couldn't find JqueryMVCFormUrlEncodedFormatter when HttpConfiguration had

 private static MediaTypeFormatterCollection DefaultFormatters()    {      MediaTypeFormatterCollection formatterCollection = new MediaTypeFormatterCollection();      formatterCollection.Add((MediaTypeFormatter) new JQueryMvcFormUrlEncodedFormatter());      return formatterCollection;    }

Now if I take a LongRequest as a method parameter it does work great, but I think I've gotten attached to dealing with HttpRequestMessage and HttpResponseMessage directly, and having ReadAsAsync<> not be able to handle this case without passing the JqueryMVCFormUrlEncodedFormatter explicitly somehow just seems not good enough.

Seems like the real right answer is that FormUrlEncodedMediaTypeFormatter should be able to handle the same thing as JqueryMVCFormUrlEncodedFormatter and there should only be 1 default FormEncoded formatter?