【发布时间】:2020-11-13 02:05:22
【问题描述】:
我遇到了一个服务向我返回 HTTP 标头的问题:
Content-Type: application/json; charset=utf-16
当它被 C# 序列化时,它会以 UTF-8 流结束,这显然会中断。似乎 utf-16 是IANA spec 中的有效编码。那么为什么这段代码不起作用呢?
System.Net.Http.HttpClient httpClient ...;
using (var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
{
//response.Content.Headers.ContentType.CharSet = "utf-16"
using (var responseContentStream = await response.Content.ReadAsStreamAsync())
{
using (var streamReader = new StreamReader(stream))
{
//streamReader.CurrentEncoding.BodyName returns utf-8 here?!
}
}
}
所以最初response 看起来不错,但一旦它到达streamReader,它似乎恢复为utf-8。为什么?
【问题讨论】:
-
您似乎期望
StreamReader(将单个字节转换为字符串)仅从流中确定编码。 -
如果内容足够小,请使用
response.Content.ReadAsStringAsync()——它具有使用正确编码的聪明才智。如果你使用StreamReader,你只是给它一个Stream,没有关于使用编码的信息 -
当客户端和服务器连接时发生协商,服务器上的网页标头和请求中的标头用于确定常见的操作模式。在某些情况下,服务器会忽略客户端标头,而在其他情况下,服务器将支持客户端标头中的模式。例如,服务器可能同时支持英语和法语。因此,服务器使用来自客户端的标头来确定使用正确语言的主页。每个服务器都是不同的。您是否在请求中包含了字符集。在某些情况下,语言决定了编码。
-
HttpContent 在使用
ReadAsStringAsync()时使用this logic 来确定响应的编码。如果你使用ReadAsStreamAsync(),那么当然不会运行任何代码。 -
@Liam 流只是字节的集合,仅此而已。没有编码的概念,因为任何旧的任意流都可能不代表文本!
标签: c# encoding http-headers content-type asp.net-core-3.1