Нет MediaTypeFormatter, доступного для чтения объекта типа 'String' из содержимого с типом медиа 'text/plain'

Это ситуация:

Это внешний веб-сервис в Servoy, и я хочу использовать этот сервис в приложении ASP.NET MVC.

С помощью этого кода я пытаюсь получить данные из сервиса:

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;

но когда я запускаю приложение, я получаю следующую ошибку:

Нет MediaTypeFormatter, доступного для чтения объекта типа 'String' из содержимого с типом медиа 'text/plain'.

Если я открываю Fiddler и запускаю тот же URL-адрес, я вижу правильные данные, но тип содержимого - text/plain. Однако я вижу в Fiddler также JSON, который я хочу...

Возможно ли решить это на стороне клиента или это веб-сервис Servoy?

Обновить:
Использовал HttpWebRequest вместо HttpResponseMessage и читал ответ с помощью StreamReader...

2 ответа

Решение

Попробуйте вместо этого использовать ReadAsStringAsync().

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

Причина, почему это ReadAsAsync<string>() не работает, потому что ReadAsAsync<> постараюсь использовать один из значений по умолчанию MediaTypeFormatter (т.е. JsonMediaTypeFormatter, XmlMediaTypeFormatter,...) читать содержимое с content-type из text/plain, Тем не менее, ни один из стандартного форматера не может прочитать text/plain (они могут только читать application/json, application/xml, так далее).

Используя ReadAsStringAsync()содержимое будет читаться как строка независимо от типа содержимого.

Или вы можете просто создать свой собственный MediaTypeFormatter, Я использую это для text/html, Если вы добавите text/plain к этому, это будет работать и для вас

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;
    }
}

Наконец, вы должны назначить это HttpMethodContext.ResponseFormatter имущество.

Я знаю, что это старый вопрос, но я почувствовал, что ответ от t3chb0t привел меня к лучшему пути, и мне t3chb0t поделиться. Вам даже не нужно заходить так далеко, чтобы реализовать все методы средства форматирования. Я сделал следующее для типа содержимого "application/vnd.api+json", возвращаемого используемым мной API:

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

Что можно использовать просто так:

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);

Супер просто и работает именно так, как я ожидал.

Другие вопросы по тегам