将Curl PUT命令转为C# HttpClient代码遇连接失败问题排查
Curl转C# PUT请求失败问题排查
原始Curl命令
curl -X PUT --data-binary @Invoice_AGL_20210408.003.xml --user [xxxx]:[xxxxxxxxxxxxxxx] https://sftp.voxelgroup.net:19922/outbox/Invoice_AGL_20210408.003.xml
你的错误代码
using (var httpClient = new HttpClient()) { using (var request = new HttpRequestMessage(new HttpMethod("PUT"), "https://sftp.voxelgroup.net:19922/outbox/Invoice_AGL_20210408.003.xml")) { var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("[xxxx]:[xxxxxxxxxxxxxxx]")); request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}"); request.Content = new StringContent(new StringContent(File.ReadAllText(@"C:\inetpub\AstroWeb\BavelExport\2022_10_29_03_16\Invoice20220016014.xml"))); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded"); var response = await httpClient.SendAsync(request); } }
代码中的问题点
- 嵌套的StringContent:双重包装
StringContent会导致实际发送的是内层对象的字符串表示,而非文件的真实内容。 - 错误的Content-Type:Curl的
--data-binary是直接发送二进制XML数据,应设置application/xml或text/xml,而非表单编码格式application/x-www-form-urlencoded。 - 文本读取文件的隐患:
File.ReadAllText会按系统默认编码读取XML,可能引发编码转换错误,用二进制读取更贴合--data-binary的原始行为。 - 认证头写法不规范:没必要用
TryAddWithoutValidation,直接使用AuthenticationHeaderValue更可靠。
修正后的代码
// 推荐复用HttpClient,避免频繁创建销毁连接资源 private static readonly HttpClient _httpClient = new HttpClient(); public async Task UploadInvoiceFileAsync() { var targetUrl = "https://sftp.voxelgroup.net:19922/outbox/Invoice_AGL_20210408.003.xml"; var authCredentials = "[xxxx]:[xxxxxxxxxxxxxxx]"; var localFilePath = @"C:\inetpub\AstroWeb\BavelExport\2022_10_29_03_16\Invoice20220016014.xml"; using (var request = new HttpRequestMessage(HttpMethod.Put, targetUrl)) { // 设置基础认证头 var base64AuthString = Convert.ToBase64String(Encoding.ASCII.GetBytes(authCredentials)); request.Headers.Authorization = new AuthenticationHeaderValue("Basic", base64AuthString); // 以二进制形式读取文件,对应curl的--data-binary参数 var fileContentBytes = File.ReadAllBytes(localFilePath); request.Content = new ByteArrayContent(fileContentBytes); // 设置正确的XML内容类型 request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/xml"); var response = await _httpClient.SendAsync(request); // 添加响应检查,请求失败时抛出异常,便于排查问题 response.EnsureSuccessStatusCode(); } }
内容的提问来源于stack exchange,提问作者nadun
相关产品推荐
相关产品推荐

