没有MediaTypeFormatter可用于从媒体类型为“text / plain”的内容中读取“String”类型的对象

时间:2012-09-20 12:23:05

标签: c# .net asp.net-mvc json httpclient

情况就是这样:

他们是Servoy中的外部Web服务,我想在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 Web服务?

更新
使用HttpWebRequest而不是HttpResponseMessage并使用StreamReader读取响应...

3 个答案:

答案 0 :(得分:80)

尝试使用ReadAsStringAsync()。

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

ReadAsAsync<string>()不起作用的原因是ReadAsAsync<>会尝试使用其中一个默认MediaTypeFormatter(即JsonMediaTypeFormatterXmlMediaTypeFormatter, ...)阅读content-type text/plain的内容。但是,默认格式化程序都无法读取text/plain(它们只能读取application/jsonapplication/xml等。

使用ReadAsStringAsync(),无论内容类型如何,内容都将被读取为字符串。

答案 1 :(得分:2)

或者您可以创建自己的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属性。

答案 2 :(得分:2)

我知道这是一个比较老的问题,但是我感到t3chb0t的回答将我带到了最佳途径,并且感觉像是分享。您甚至不需要执行所有格式化程序的方法。对于由我使用的API返回的内容类型“ application / vnd.api + json”,我做了以下操作:

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

超级简单,完全符合我的预期。