C# 如何处理传输编码:使用.NET Core HttpClient.PostAsync下载文件时分块 处境
我正在使用HttpClient(System.Net.Http,Version=4.2.1.0)将包含多部分表单数据的Http请求发布到web API。表单数据包括一个字符串参数(C# 如何处理传输编码:使用.NET Core HttpClient.PostAsync下载文件时分块 处境,c#,.net-core,httpclient,transfer-encoding,C#,.net Core,Httpclient,Transfer Encoding,我正在使用HttpClient(System.Net.Http,Version=4.2.1.0)将包含多部分表单数据的Http请求发布到web API。表单数据包括一个字符串参数(benchmark)和一个文件(addressFile),该文件包含在流中。API调用返回我要保存到磁盘的CSV文件 响应包含头Transfer Encoding:chunked,而responseBytes中包含的数据包括块头。我希望HttpClient库去掉这些头,它们是实际内容的元数据。相反,它只是在内容中包含标
benchmark
)和一个文件(addressFile
),该文件包含在流中。API调用返回我要保存到磁盘的CSV文件
响应包含头Transfer Encoding:chunked
,而responseBytes
中包含的数据包括块头。我希望HttpClient库去掉这些头,它们是实际内容的元数据。相反,它只是在内容中包含标题行
问题:
处理这些块头的正确方法是什么
我当然可以自己编写一个方法来处理头部,但我发现很难相信HttpClient库中还没有这个功能
代码
结果
注意第一行和后续行上的区块标题(0fe8
,0060
,0fe8
)
预期结果
我希望头被HttpClient库剥离
"AK0000036228","500 HOLLYWOOD DR, ANCHORAGE, AK, 99501","Match","Exact","500 HOLLYWOOD DR, ANCHORAGE, AK, 99501","-149.87424,61.23034","190797469","R"
"AK0000363994","3155 E 18TH CIR, ANCHORAGE, AK, 99508","Match","Non_Exact","3155 E 18TH CIR, ANCHORAGE, AK, 99508","-149.82193,61.20462","190799569","L"
"AK0000228718","1050 ASPEN ST, FAIRBANKS, AK, 99709-5501","Match","Exact","1050 ASPEN ST, FAIRBANKS, AK, 99709","-147.7731,64.8535","605310042","L"
"AK0000536714","SMITH COVE IN SMITH LAGOON T74S R86E CRM S17 & 20, KASAAN, AK, 99901","No_Match"
"AK0001413822","USS-12403, N BANK WOOD RIVER, ALEKNAGIK, AK, 99555","No_Match"
"AK0000489567","BREAKWATER BTWN WESTERN AVE & TAIT ST, METLAKATLA, AK, 99926","No_Match"
我最终编写了这个扩展方法,它在我的用例中表现得足够好
public static Task<Stream> ReadAsStreamAsync(this HttpContent content, bool isChunked)
{
if (!isChunked)
{
return content.ReadAsStreamAsync();
}
else
{
var task = content.ReadAsStreamAsync()
.ContinueWith<Stream>((streamTask) =>
{
var outputStream = new MemoryStream();
var buffer = new char[1024 * 1024];
var stream = streamTask.Result;
// No using() so that we don't dispose stream.
var tr = new StreamReader(stream);
var tw = new StreamWriter(outputStream);
while (!tr.EndOfStream)
{
var chunkSizeStr = tr.ReadLine().Trim();
var chunkSize = int.Parse(chunkSizeStr, System.Globalization.NumberStyles.HexNumber);
tr.ReadBlock(buffer, 0, chunkSize);
tw.Write(buffer, 0, chunkSize);
tr.ReadLine();
}
return outputStream;
});
return task;
}
}
public static Task ReadAsStreamAsync(此HttpContent,bool为chunked)
{
如果(!isChunked)
{
返回content.ReadAsStreamAsync();
}
其他的
{
var task=content.ReadAsStreamAsync()
.ContinueWith((流任务)=>
{
var outputStream=new MemoryStream();
var buffer=新字符[1024*1024];
var stream=streamTask.Result;
//不使用()以便不处理流。
var tr=新的StreamReader(stream);
var tw=新的StreamWriter(outputStream);
而(!tr.EndOfStream)
{
var chunksizest=tr.ReadLine().Trim();
var chunkSize=int.Parse(chunksizest,System.Globalization.NumberStyles.HexNumber);
tr.ReadBlock(缓冲区,0,chunkSize);
tw.Write(缓冲区,0,chunkSize);
tr.ReadLine();
}
返回输出流;
});
返回任务;
}
}
如果响应仅为文本。Httpclient自动处理它(仅用于字符串)
"AK0000036228","500 HOLLYWOOD DR, ANCHORAGE, AK, 99501","Match","Exact","500 HOLLYWOOD DR, ANCHORAGE, AK, 99501","-149.87424,61.23034","190797469","R"
"AK0000363994","3155 E 18TH CIR, ANCHORAGE, AK, 99508","Match","Non_Exact","3155 E 18TH CIR, ANCHORAGE, AK, 99508","-149.82193,61.20462","190799569","L"
"AK0000228718","1050 ASPEN ST, FAIRBANKS, AK, 99709-5501","Match","Exact","1050 ASPEN ST, FAIRBANKS, AK, 99709","-147.7731,64.8535","605310042","L"
"AK0000536714","SMITH COVE IN SMITH LAGOON T74S R86E CRM S17 & 20, KASAAN, AK, 99901","No_Match"
"AK0001413822","USS-12403, N BANK WOOD RIVER, ALEKNAGIK, AK, 99555","No_Match"
"AK0000489567","BREAKWATER BTWN WESTERN AVE & TAIT ST, METLAKATLA, AK, 99926","No_Match"
public static Task<Stream> ReadAsStreamAsync(this HttpContent content, bool isChunked)
{
if (!isChunked)
{
return content.ReadAsStreamAsync();
}
else
{
var task = content.ReadAsStreamAsync()
.ContinueWith<Stream>((streamTask) =>
{
var outputStream = new MemoryStream();
var buffer = new char[1024 * 1024];
var stream = streamTask.Result;
// No using() so that we don't dispose stream.
var tr = new StreamReader(stream);
var tw = new StreamWriter(outputStream);
while (!tr.EndOfStream)
{
var chunkSizeStr = tr.ReadLine().Trim();
var chunkSize = int.Parse(chunkSizeStr, System.Globalization.NumberStyles.HexNumber);
tr.ReadBlock(buffer, 0, chunkSize);
tw.Write(buffer, 0, chunkSize);
tr.ReadLine();
}
return outputStream;
});
return task;
}
}
string result = await response.Content.ReadAsStringAsync();