`ReadAsAsync<string>`和`ReadAsStringAsync`应该用于什么?

15

HttpContentExtensions.ReadAsAsync<string>HttpContent.ReadAsStringAsync应该用于什么?

它们似乎做着相似的事情,但使用方式却很奇怪。以下是一些测试及其输出结果。在某些情况下,会抛出JsonReaderException异常,在某些情况下,JSON会被输出,但带有额外的转义字符。

我已经在我的代码库中使用了这两个函数,但希望能够理解它们应该如何工作,以便选择一个进行对齐。

//Create data and serialise to JSON
var data = new
{
    message = "hello world"
};
string dataAsJson = JsonConvert.SerializeObject(data);

//Create request with data
HttpConfiguration config = new HttpConfiguration();
HttpRequestMessage request = new HttpRequestMessage();
request.SetConfiguration(config);
request.Method = HttpMethod.Post;
request.Content = new StringContent(dataAsJson, Encoding.UTF8, "application/json");

string requestContentT = request.Content.ReadAsAsync<string>().Result; // -> JsonReaderException: Error reading string.Unexpected token: StartObject.Path '', line 1, position 1.
string requestContentS = request.Content.ReadAsStringAsync().Result; // -> "{\"message\":\"hello world\"}"

//Create response from request with same data
HttpResponseMessage responseFromRequest = request.CreateResponse(HttpStatusCode.OK, dataAsJson, "application/json");

string responseFromRequestContentT = responseFromRequest.Content.ReadAsAsync<string>().Result; // -> "{\"message\":\"hello world\"}"
string responseFromRequestContentS = responseFromRequest.Content.ReadAsStringAsync().Result; // -> "\"{\\\"message\\\":\\\"hello world\\\"}\""

//Create a standalone new response
HttpResponseMessage responseNew = new HttpResponseMessage();
responseNew.Content = new StringContent(dataAsJson, Encoding.UTF8, "application/json");

string responseNewContentT = responseNew.Content.ReadAsAsync<string>().Result; // -> JsonReaderException: Error reading string.Unexpected token: StartObject.Path '', line 1, position 1.
string responseNewContentS = responseNew.Content.ReadAsStringAsync().Result; // -> "{\"message\":\"hello world\"}"
1个回答

12

ReadAsStringAsync:这是一个基本的“将内容作为字符串获取”的方法。它适用于任何类型的内容,因为它只是处理字符串。

ReadAsAsync<T>:这个方法旨在将JSON响应反序列化为对象。它失败的原因是返回的JSON不是表示单个字符串的有效JSON。例如,如果您对字符串进行序列化:

var result = JsonConvert.SerializeObject("hello world");
Console.WriteLine(result);

输出结果为:

"hello world"

请注意它被双引号包围。如果您尝试将任意JSON直接反序列化为不在格式"....."中的字符串,它将抛出您看到的异常,因为它期望JSON以"开头。


1
ReadAsAsync<T> 可能只是一个包装器,用于 JsonConvert.DeserializeObject<T>(await ReadAsStringAsync()) - Camilo Terevinto
@CamiloTerevinto 实际上不是这样。ReadAsAsync<T> 更加聪明,因为它不会先将字符串读入内存再创建对象。 - DavidG
1
有趣的是,David Fowler发起了一条关于这个话题的伟大Twitter线程(如果你不知道他是谁...真可惜哈哈)https://twitter.com/davidfowl/status/1010403287521095680 - DavidG
我真该感到惭愧,因为我没有使用 Twitter(但我确实认识他)。根据这个,它使用的是流而不是字符串...很有趣的阅读。谢谢! - Camilo Terevinto
1
@CamiloTerevinto 我不是很擅长使用 Twitter,但 Fowler 和 Damian Edwards 非常值得关注,而且非常乐于回答问题。 - DavidG
1
哦,而且直播的ASP.NET社区聚会(http://live.asp.net)也非常有用。 - DavidG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接