无法使用 C# HttpClient 上传文件,Postman 工作正常
Cannot Upload File using C# HttpClient, Postman works OK
我正在尝试 post 一个文件到 iManage 服务器 REST 接口(Apache 服务器,java 后端??不确定)。 Postman 工作正常,但是当我从 C# .NET CORE 3.1 尝试它时,我得到这样的响应:
{
“错误”: {
“代码”:“文件上传失败”,
"message": "文件上传失败"
}
}
任何人有任何想法我可以尝试吗?谢谢!
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.IO;
using System.Text;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static async Task Main(string[] args)
{
Uri url = new Uri("https://iManageServer.net/");
string filename = @"C:\Temp\temp.txt";
string token = "E4vt1DzXcnkQTmOUspN6TG6KLR7TClCPPbjyvHsu9TRlKvND9gO4xTPYIEYy0+Lu";
const string folderId = "MyFolderId";
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var content = new MultipartFormDataContent($"{DateTime.Now.Ticks:x}"))
{
var jsonString = JsonConvert.SerializeObject(new { warnings_for_required_and_disabled_fields = true, doc_profile = new { name = Path.GetFileNameWithoutExtension(filename), extension = Path.GetExtension(filename).TrimStart('.'), size = fs.Length } });
HttpContent httpContent = new StringContent(jsonString, Encoding.UTF8);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var c1 = httpContent;
content.Add(c1, "\"json\"");
var c2 = new StreamContent(fs);
c2.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
content.Add(c2, "\"file\"");
c2.Headers.ContentDisposition.FileName = $"\"{filename}\"";
c2.Headers.ContentDisposition.FileNameStar = null;
var hch = new HttpClientHandler();
hch.ServerCertificateCustomValidationCallback += (sender, cert, chain, error) => true;
using (var httpClient = new HttpClient(hch) { BaseAddress = url })
{
httpClient.DefaultRequestHeaders.Add("User-Agent", "PostmanRuntime/7.26.5");
httpClient.DefaultRequestHeaders.Add("Accept", "*/*");
httpClient.DefaultRequestHeaders.Add("Connection", "keep-alive");
using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, $"folders/{folderId}/documents"))
{
requestMessage.Headers.Add("X-Auth-Token", token);
requestMessage.Content = content;
var response = await httpClient.SendAsync(requestMessage);
string jsonResponse = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
//never hits
}
else
{
System.Diagnostics.Debug.WriteLine(jsonResponse);
//{
// "error": {
// "code": "FileUploadFailure",
// "message": "File upload failure"
// }
//}
}
}
}
}
}
}
}
}
邮递员工作正常。以下是两者的 Wireshark 跟踪:
Postman 首先是 C# 结果:
引用了 MultipartFormDataContent 上的边界。 iManage API 不喜欢那样。
我必须在内容实例化后立即添加以下代码:
var boundary = $"-------------------------{DateTime.Now.Ticks:x}";
content.Headers.Remove("Content-Type");
content.Headers.TryAddWithoutValidation("Content-Type", $"multipart/form-data; boundary={boundary}");
content.GetType().BaseType.GetField("_boundary", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(content, boundary);
我正在尝试 post 一个文件到 iManage 服务器 REST 接口(Apache 服务器,java 后端??不确定)。 Postman 工作正常,但是当我从 C# .NET CORE 3.1 尝试它时,我得到这样的响应:
{ “错误”: { “代码”:“文件上传失败”, "message": "文件上传失败" } }
任何人有任何想法我可以尝试吗?谢谢!
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.IO;
using System.Text;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static async Task Main(string[] args)
{
Uri url = new Uri("https://iManageServer.net/");
string filename = @"C:\Temp\temp.txt";
string token = "E4vt1DzXcnkQTmOUspN6TG6KLR7TClCPPbjyvHsu9TRlKvND9gO4xTPYIEYy0+Lu";
const string folderId = "MyFolderId";
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var content = new MultipartFormDataContent($"{DateTime.Now.Ticks:x}"))
{
var jsonString = JsonConvert.SerializeObject(new { warnings_for_required_and_disabled_fields = true, doc_profile = new { name = Path.GetFileNameWithoutExtension(filename), extension = Path.GetExtension(filename).TrimStart('.'), size = fs.Length } });
HttpContent httpContent = new StringContent(jsonString, Encoding.UTF8);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var c1 = httpContent;
content.Add(c1, "\"json\"");
var c2 = new StreamContent(fs);
c2.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
content.Add(c2, "\"file\"");
c2.Headers.ContentDisposition.FileName = $"\"{filename}\"";
c2.Headers.ContentDisposition.FileNameStar = null;
var hch = new HttpClientHandler();
hch.ServerCertificateCustomValidationCallback += (sender, cert, chain, error) => true;
using (var httpClient = new HttpClient(hch) { BaseAddress = url })
{
httpClient.DefaultRequestHeaders.Add("User-Agent", "PostmanRuntime/7.26.5");
httpClient.DefaultRequestHeaders.Add("Accept", "*/*");
httpClient.DefaultRequestHeaders.Add("Connection", "keep-alive");
using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, $"folders/{folderId}/documents"))
{
requestMessage.Headers.Add("X-Auth-Token", token);
requestMessage.Content = content;
var response = await httpClient.SendAsync(requestMessage);
string jsonResponse = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
//never hits
}
else
{
System.Diagnostics.Debug.WriteLine(jsonResponse);
//{
// "error": {
// "code": "FileUploadFailure",
// "message": "File upload failure"
// }
//}
}
}
}
}
}
}
}
}
邮递员工作正常。以下是两者的 Wireshark 跟踪:
Postman 首先是 C# 结果:
引用了 MultipartFormDataContent 上的边界。 iManage API 不喜欢那样。 我必须在内容实例化后立即添加以下代码:
var boundary = $"-------------------------{DateTime.Now.Ticks:x}";
content.Headers.Remove("Content-Type");
content.Headers.TryAddWithoutValidation("Content-Type", $"multipart/form-data; boundary={boundary}");
content.GetType().BaseType.GetField("_boundary", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(content, boundary);