Нет 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);
Супер просто и работает именно так, как я ожидал.