You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HttpClient上传CSV文件后出现乱码及额外行问题排查

上传CSV后下载出现额外头部行的问题

我用HttpClient上传CSV文件的代码如下:

string token = await GetTokenAsync();
string path = "C://...";
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Token {token}");
MultipartContent content = new();
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "dtes_acreedor_.csv" };
string contenido = await File.ReadAllTextAsync(path);
StringContent contentData = new(contenido, Encoding.UTF8, "text/csv");
content.Add(contentData);
HttpResponseMessage response = await _httpClient.PutAsync("api/v1/resources/auxiliary-files/", content);

上传后下载文件,之前遇到过乱码问题(已经尝试过指定UTF-8编码读写文件,甚至上传未格式化的其他文件也有同样问题),现在更关键的是下载后的文件开头多了3行额外内容。

我生成CSV文件的代码是:

File.WriteAllText(name, csv.ToString(), Encoding.UTF8);

问题根源分析

你遇到的额外行问题,核心原因是错误地配置了MultipartContent的结构:

当你直接给MultipartContent设置ContentDisposition为attachment,并把CSV内容作为子内容添加进去时,Multipart请求本身会自动生成边界分隔符、头部描述等内容。如果后端服务器没有正确解析Multipart请求,而是直接把整个请求体保存为文件,这些Multipart的结构行就会被写入到文件里,也就是你看到的开头那3行多余内容。

另外,用StringContent读取文件内容再转成字节,虽然指定了UTF-8,但如果文件本身有BOM或者特殊编码场景,也可能引发乱码——不过你说现在乱码不是重点,我们先解决额外行的问题。

修复方案

根据后端API的要求,有两种正确的上传方式:

方案1:直接上传原始CSV内容(如果API接受text/csv请求体)

如果后端API可以直接接收原始的CSV内容,不需要Multipart格式,那最简单的方式就是直接发送文件字节:

string token = await GetTokenAsync();
string path = "C://...";
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Token {token}");

// 直接读取文件字节,避免编码转换可能带来的问题
byte[] fileBytes = await File.ReadAllBytesAsync(path);
var content = new ByteArrayContent(fileBytes);
content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
// 如果API需要文件名标识,添加Content-Disposition请求头
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = "dtes_acreedor_.csv"
};

var response = await _httpClient.PutAsync("api/v1/resources/auxiliary-files/", content);

方案2:正确配置Multipart/form-data(如果API要求该格式)

如果后端明确要求用multipart/form-data格式上传文件,你需要给子内容设置ContentDisposition,而不是父MultipartContent:

string token = await GetTokenAsync();
string path = "C://...";
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Token {token}");

var multipartContent = new MultipartFormDataContent();
byte[] fileBytes = await File.ReadAllBytesAsync(path);
var fileContent = new ByteArrayContent(fileBytes);
fileContent.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
// 这里的Name要和后端API接收文件的参数名一致(比如后端用request.Files["file"]接收,就填"file")
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
    Name = "file",
    FileName = "dtes_acreedor_.csv"
};
multipartContent.Add(fileContent);

var response = await _httpClient.PutAsync("api/v1/resources/auxiliary-files/", multipartContent);

额外建议

  • 优先用ByteArrayContent读取文件字节,比StringContent更可靠,能避免编码转换过程中可能出现的乱码或字符丢失问题。
  • 确认后端API的文档:明确要求的上传格式是text/csv还是multipart/form-data,这决定了你应该用哪个方案。

内容的提问来源于stack exchange,提问作者sergioocode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:49:08