Update to MVC4 RC: No MediaTypeFormatter is available for reading an object of type "TestRequestModel" from content with a media type of '' undefined ''

I am using the beta version of MVC4 and am currently working on upgrading to the recently released RC version.

It seems that the complex types of queries with model binding have changed , but I can't figure out how / what I'm doing wrong.

For example, let's say I have the following API controller:

public class HomeApiController : ApiController { public TestModel Get() { return new TestModel { Id = int.MaxValue, Description = "TestDescription", Time = DateTime.Now }; } } 

This gives the expected result:

 <TestModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/xxxx"> <Description>TestDescription</Description> <Id>2147483647</Id> <Time>2012-06-07T10:30:01.459147-04:00</Time> </TestModel> 

Now say that I'm just changing the signature, accepting the type of request, for example:

 public TestModel Get(TestRequestModel request) { ... public class TestRequestModel { public int? SomeParameter { get; set; } } 

Now I get the following error:

 <Exception xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/System.Web.Http.Dispatcher"> <ExceptionType>System.InvalidOperationException</ExceptionType> <Message> No MediaTypeFormatter is available to read an object of type 'TestRequestModel' from content with media type ''undefined''. </Message> <StackTrace> at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger) at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger) at System.Web.Http.ModelBinding.FormatterParameterBinding.ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) at System.Web.Http.Controllers.HttpActionBinding.<>c__DisplayClass1.<ExecuteBindingAsync>b__0(HttpParameterBinding parameterBinder) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Threading.Tasks.TaskHelpers.IterateImpl(IEnumerator`1 enumerator, CancellationToken cancellationToken) </StackTrace> </Exception> 

I looked at the source where this exception was thrown in HttpContentExtensions , but it looks like it checks the content headers (which I should have) and if it doesn’t have what it is trying to get the formatter from the MediaTypeFormatter collection that it has for a specific type ( which he cannot) and then throws.

Has anyone else experienced this? Am I missing some global registration?

+8
asp.net-mvc asp.net-web-api asp.net-mvc-4 model-binding
source share
2 answers

I see that your original question has been answered, but to answer another, the model binding has changed somewhat in RC.

http://weblogs.thinktecture.com/cweyer/2012/06/aspnet-web-api-changes-from-beta-to-rc.html

There is some information about this in this link. But summing up the changes that seem to affect you, model binding pulls its values ​​either from the body or from the request uri. This is true for previous releases, but with a candidate for release MVC4 will by default look for a body for complex types and uri for value types.

So, if you send a body with a request containing the key "SomeParameter", you should see its binding. Or you can link to the URL if you change the declaration to:

  public TestModel Get(int? someParameter) { } 

Fortunately, the team anticipated potential problems with this and left us with attributes that we could use to override this behavior.

  public TestModel Get([FromUri]TestRequestModel request) { } 

The key point here is [FromUri] , which tells the model middleware to look at the uri values. There is also [FromBody] if you want to put a value type in the request body.

+13
source share

We saw the same thing. In our case, the problem was a complex object passed to the get method. We needed to add the [FromUri] attribute to the parameter to this method.

http://forums.asp.net/t/1809925.aspx/1?GET+requests+with+complex+object+as+input+parameter

 public class SearchController : ApiController { // added [FromUri] in beta to RC transition otherwise media type formatter error public IQueryable<SearchResultEventModel> Get( [FromUri]SearchSpecModel search ) { // ... } } 
+2
source share

All Articles