Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot Upload File using C# HttpClient, Postman works OK

I am trying to post a file to an iManage server REST interface (Apache server, java backend?? not sure). Postman works fine, but when I try it from C# .NET CORE 3.1 I get a response like so:

{ "error": { "code": "FileUploadFailure", "message": "File upload failure" } }

Anyone have any ideas I can try? Thanks!

<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 works fine. Here is what the Wireshark trace looks like for both:

Postman is First then the C# result: Postman

C#

like image 887
Corey Avatar asked Sep 28 '20 13:09

Corey


People also ask

Why can't I upload files from Excel to edge?

Edge seems to require exclusive access to files when uploading them. Excel and Word only allow read access to opened documents, causing Edge to not accept the file for upload. Simply closing your document before uploading should fix you problem.

Where are the files that I upload to the application saved?

The files that you upload from this application are saved in the location: C:\inetpub\wwwroot\ApplicationName on the local hard disk. To make this application work in the .NET Framework, allow Full Control access to the ASPNET user. To do this, follow these steps: Locate the application folder in Windows Explorer.

How do I upload an image file to my application?

On the Debug menu, click Start to build and to run the application. A text box and a command button appear. Type the path of the image file in the text box, or click Browse to locate the image file on your local computer. Click Upload to send the file to the server. If the file is unique, you receive a message that the upload succeeded.

How do I upload a file to the server?

Click Upload to send the file to the server. If the file is unique, you receive a message that the upload succeeded. If the file already exists on the server, you receive an appropriate message. The files that you upload from this application are saved in the location: C:\inetpub\wwwroot\ApplicationName on the local hard disk.


1 Answers

The Boundary on the MultipartFormDataContent was quoted. The iManage API did not like that. I had to add the following code right after the instantiation of the content:

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);
like image 107
Corey Avatar answered Oct 09 '22 00:10

Corey