No MediaTypeFormatter is available to read an object of type 'String' from content with media type 'text/plain'

121,991

Solution 1

Try using ReadAsStringAsync() instead.

 var foo = resp.Content.ReadAsStringAsync().Result;

The reason why it ReadAsAsync<string>() doesn't work is because ReadAsAsync<> will try to use one of the default MediaTypeFormatter (i.e. JsonMediaTypeFormatter, XmlMediaTypeFormatter, ...) to read the content with content-type of text/plain. However, none of the default formatter can read the text/plain (they can only read application/json, application/xml, etc).

By using ReadAsStringAsync(), the content will be read as string regardless of the content-type.

Solution 2

Or you can just create your own MediaTypeFormatter. I use this for text/html. If you add text/plain to it, it'll work for you too:

public class TextMediaTypeFormatter : MediaTypeFormatter
{
    public TextMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
    }

    public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
    {
        return ReadFromStreamAsync(type, readStream, content, formatterLogger, CancellationToken.None);
    }

    public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
    {
        using (var streamReader = new StreamReader(readStream))
        {
            return await streamReader.ReadToEndAsync();
        }
    }

    public override bool CanReadType(Type type)
    {
        return type == typeof(string);
    }

    public override bool CanWriteType(Type type)
    {
        return false;
    }
}

Finally you have to assign this to the HttpMethodContext.ResponseFormatter property.

Solution 3

I know this is an older question, but I felt the answer from t3chb0t led me to the best path and felt like sharing. You don't even need to go so far as implementing all the formatter's methods. I did the following for the content-type "application/vnd.api+json" being returned by an API I was using:

public class VndApiJsonMediaTypeFormatter : JsonMediaTypeFormatter
{
    public VndApiJsonMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/vnd.api+json"));
    }
}

Which can be used simply like the following:

HttpClient httpClient = new HttpClient("http://api.someaddress.com/");
HttpResponseMessage response = await httpClient.GetAsync("person");

List<System.Net.Http.Formatting.MediaTypeFormatter> formatters = new List<System.Net.Http.Formatting.MediaTypeFormatter>();
formatters.Add(new System.Net.Http.Formatting.JsonMediaTypeFormatter());
formatters.Add(new VndApiJsonMediaTypeFormatter());

var responseObject = await response.Content.ReadAsAsync<Person>(formatters);

Super simple and works exactly as I expected.

Share:
121,991
Renzzs
Author by

Renzzs

Updated on August 09, 2020

Comments

  • Renzzs
    Renzzs almost 4 years

    This is the situation:

    Their is a external webservice in Servoy and I want to use this service in a ASP.NET MVC applicatie.

    With this code I attempt to get the data from the service:

    HttpResponseMessage resp = client.GetAsync("http://localhost:8080/servoy-service/iTechWebService/axws/shop/_authenticate/mp/112818142456/82cf1988197027955a679467c309274c4b").Result;
    resp.EnsureSuccessStatusCode();
    
    var foo = resp.Content.ReadAsAsync<string>().Result;
    

    but when I run the application I get the next error:

    No MediaTypeFormatter is available to read an object of type 'String' from content with media type 'text/plain'.

    If I open Fiddler and run the same url, I see the right data but the content-type is text/plain. However I see in Fiddler also the JSON that I want...

    Is it possible to solve this at client side or is it the Servoy webservice?

    Update:
    Used HttpWebRequest instead of HttpResponseMessage and read the response with StreamReader...

  • Eric Furspan
    Eric Furspan over 7 years
    I am having this same problem, except the error message is "No MediaTypeFormatter is available to read an object of type 'Int32' from content with media type 'text/html'." Is there a similar solution for int32?
  • Jav_1
    Jav_1 over 7 years
    Quanda: You can use return JsonConvert.DeserializeObject<Int32>(resultString);, result String is the result after ReadAsStringAsync(), JsonConvert is from Newtonsoft.Json. You can download this library from NuGet. This is also very useful for Portable Libraries and not only applies to Int32, It applies to almost every type or class.
  • user2837480
    user2837480 almost 3 years
    I get similar kind of issue for object of type 'FileStreamResult' from content with media type 'text/calendar'. How can I fix this? API is returning iCal (File stream)