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

问题描述 投票:0回答:3

情况是这样的:

他们是 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”类型的对象 来自媒体类型为“文本/纯文本”的内容。

如果我打开 Fiddler 并运行相同的 url,我会看到正确的数据,但内容类型是文本/纯文本。不过我在 Fiddler 中也看到了我想要的 JSON...

是否可以在客户端解决这个问题,或者是 Servoy Web 服务?

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

c# .net asp.net-mvc json httpclient
3个回答
144
投票

尝试使用 ReadAsStringAsync() 代替。

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

ReadAsAsync<string>()
不起作用的原因是因为
ReadAsAsync<>
会尝试使用默认的
MediaTypeFormatter
之一(即
JsonMediaTypeFormatter
XmlMediaTypeFormatter
,...)来读取带有
content-type
的内容
text/plain
。但是,默认格式化程序都无法读取
text/plain
(它们只能读取
application/json
application/xml
等)。

通过使用

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


7
投票

或者您可以创建自己的

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
属性。


6
投票

我知道这是一个较旧的问题,但我觉得 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);

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

© www.soinside.com 2019 - 2024. All rights reserved.