使用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
相关产品推荐
相关产品推荐

