Reputation: 33850
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 the Content-Type
HTTP header as text/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);
}
}
}
Upvotes: 2
Views: 24362
Reputation: 10175
How about just using ReadAsStringAsync
if your WebAPI is expecting to return content in plain text?
response.Content.ReadAsStringAsync().Result;
Upvotes: 1
Reputation: 142014
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.
Upvotes: 4