Web API: No MediaTypeFormatter is available to read an object of type 'IEnumerable`1' from content with media type 'text/plain'
Solution 1
I believe (because I don't have time to test it now) that you need to explicitly set the Status Code on the responseMessage you are passing to HttpResponseException
. Normally, HttpResponseException
will set the status code for you, but because you are providing a responsemessage explicitly, it will use the status code from that. By default, `HttpResponseMessage has a status code of 200.
So what is happening is you are getting an error on the server, but still returning a 200. Which is why your client is trying to deserialize the text/plain body produced by StringContent, as if it were an IEnumerable.
You need to set
responseMessage.StatusCode = HttpStatusCode.InternalServerError
in your exception handler on the server.
Solution 2
How about just using ReadAsStringAsync
if your WebAPI is expecting to return content in plain text?
response.Content.ReadAsStringAsync().Result;
Water Cooler v2
https://sathyaish.net/?c=pros https://www.youtube.com/user/Sathyaish
Updated on September 10, 2020Comments
-
Water Cooler v2 over 3 years
I get this error in my client (an ASP.NET MVC application) from a call to my ASP.NET Web API. I checked and the Web API is returning the data alright.
No MediaTypeFormatter is available to read an object of type 'IEnumerable`1' from content with media type 'text/plain'.
I believe that I can inherit from
DataContractSerializer
and implement my own serializer which can attach theContent-Type
HTTP header astext/xml
.But my question is: is that necessary?
Because if it was, it would mean that the default
DataContractSerializer
does not set this essential header. I was wondering if Microsoft could leave such an important thing out. Is there another way out?Here's the relevant client side code:
public ActionResult Index() { HttpClient client = new HttpClient(); var response = client.GetAsync("http://localhost:55333/api/bookreview/index").Result; if (response.IsSuccessStatusCode) { IEnumerable<BookReview> reviews = response.Content.ReadAsAsync<IEnumerable<BookReview>>().Result; return View(reviews); } else { ModelState.AddModelError("", string.Format("Reason: {0}", response.ReasonPhrase)); return View(); } }
And here's the server side (Web API) code:
public class BookReviewController : ApiController { [HttpGet] public IEnumerable<BookReview> Index() { try { using (var context = new BookReviewEntities()) { context.ContextOptions.ProxyCreationEnabled = false; return context.BookReviews.Include("Book.Author"); } } catch (Exception ex) { var responseMessage = new HttpResponseMessage { Content = new StringContent("Couldn't retrieve the list of book reviews."), ReasonPhrase = ex.Message.Replace('\n', ' ') }; throw new HttpResponseException(responseMessage); } } }
-
Justin Self over 11 yearsHave you tried setting your content type for the http request you are making?
-
frictionlesspulley over 11 yearsTry switching the return type from IEnumerable to List
-
Mark Jones over 11 yearsIt looks like it is - Have you seen stackoverflow.com/questions/10428177/…
-
Darrel Miller over 11 years@justnS You don't set content-type for GET requests. Only when you are sending a body i.e. PUT, POST, PATCH.
-
-
Darrel Miller over 11 yearsThe OP is only expecting a string if the server fails. I don't think your line above would actually compile.