c# - 无法使用 C# HttpClient 上传文件,Postman 工作正常

标签 c# postman httpclient imanage

我正在尝试将文件发布到 iManage 服务器 REST 接口(interface)(Apache 服务器、java 后端??不确定)。 Postman 工作正常,但是当我从 C# .NET CORE 3.1 尝试它时,我得到如下响应:
{
“错误”: {
"code": "FileUploadFailure",
"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"
                                //  }
                                //}
                            }
                        }
                    }
                }
            }
        }
    }
}
postman 工作正常。以下是两者的 Wireshark 跟踪的样子:
Postman 是 First 然后是 C# 结果:
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);

关于c# - 无法使用 C# HttpClient 上传文件,Postman 工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64102727/

相关文章:

c# - 是否可以将 SqlGeography 与 Linq to Sql 一起使用?

c# - 使用 WPF 应用程序运行多个使用 MEF 的各种应用程序

c# - 使用 Entity Framework Code First Development,我可以让它在现有数据库中创建一个或多个表吗?

c# - 类属性作为集合

java - 时区未显示

node.js - 无法提取位置的地理 key

postman - 如何忽略 Newman 中的 SSL 证书错误

c# - HTTP PATCH 方法 C#

java - setMaxForRoute 在 ThreadSafeClientConnManager 中不起作用

java - 如何在 Apache 异步客户端中配置允许的挂起请求数