locked
How to encode MultipartFormDataContent to UTF-8

    Question

  • Hello,

    I need to convert MultiPartFormDataContent to UTF-8 Format, but didn't find any way to do that, below is my code

      MultipartFormDataContent form = new MultipartFormDataContent();
    
     if (fileStream != null)
      form.Add(new StreamContent(fileStream), "somestring", fileName);

    When I pass filename as "MyFile.txt" it works Perfectly, but when I pass something like this as filename "Bayern München.txt" it converts to garbage value like this "=?utf-8?B?QmF5ZXJuIE3DvG5jaGVuLnR4dA==?=";

    Is there anything missing in the code?

    Thanks in advance.

    Monday, February 9, 2015 6:59 AM

Answers

  • Hello Herro wong,

    Thanks for the reply,

    As I said earlier, problem was on client side not on server side, finally I found the solution to fix it.

    Below is the code if anybody wants to refer(Not production ready)

     public static async Task<HttpResponseMessage> UploadFile(Stream fileStream, string fileName,....,CancellationToken cancellationToken)
            {
               
                HttpClient httpClient = null;
                HttpResponseMessage response = null;
    
    
                try
                {
    
                    httpClient = new HttpClient();
    
                    MultipartFormDataContent form = new MultipartFormDataContent();
              
    		 string formDataBoundary = "---------------------------2156852217421";
                  
                    if (fileStream != null)
                          form.Add(new StreamContent(
                                        BuildMultipartStream("someString", fileName, fileBytes , formDataBoundary)));
    
    
    
                    var httprequestMessage = new HttpRequestMessage(HttpMethod.Post, postURL);
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("user-agent", ConfigManager.UserAgent);
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html, application/xhtml+xml, */* ");
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
                    httprequestMessage.Content = form;
                    httprequestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
                    httprequestMessage.Content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue(
                        "boundary",
                        formDataBoundary));
    
                   
    
                    response = await httpClient.SendAsync(httprequestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
    
                    response.EnsureSuccessStatusCode();
    
                 
                }
                catch (Exception ex)
                {
                  
                }
    
                return response;
            }
    

       private static Stream BuildMultipartStream(string name, string fileName, byte[] fileBytes, string boundary)
            {
                // Create multipart/form-data headers.
                byte[] firstBytes = Encoding.UTF8.GetBytes(String.Format(
                    "--{0}\r\n" +
                    "Content-Dis-data; name=\"{1}\"; filename=\"{2}\"\r\n" +
                    "\r\n",
                    boundary,
                    name,
                    fileName));
    
                byte[] lastBytes = Encoding.UTF8.GetBytes(String.Format(
                    "\r\n" +
                    "--{0}--\r\n",
                    boundary));
    
                int contentLength = firstBytes.Length + fileBytes.Length + lastBytes.Length;
                byte[] contentBytes = new byte[contentLength];
    
    
                // Join the 3 arrays into 1.
                Array.Copy(
                    firstBytes,
                    0,
                    contentBytes,
                    0,
                    firstBytes.Length);
                Array.Copy(
                    fileBytes,
                    0,
                    contentBytes,
                    firstBytes.Length,
                    fileBytes.Length);
                Array.Copy(
                    lastBytes,
                    0,
                    contentBytes,
                    firstBytes.Length + fileBytes.Length,
                    lastBytes.Length);
    
                return new MemoryStream(contentBytes);
            }

    Wednesday, February 18, 2015 1:14 PM

All replies

  • Hi Zee_patel,

    What’s the type of fileStream object? Maybe FileStream class? Your code snippet is not enough for me to reproduce your issue, if possible, please post more information here.

    As far as I currently know, you can try encode the filename and decode it when you want to use.

    Convert.ToBase64String( Encoding.UTF8.GetBytes(filename))
    
    Encoding.UTF8.GetString(Convert.FromBase64String(filename))
    

    If this doesn’t help, please post a repro project, use your OneDrive and share a link here.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    Tuesday, February 10, 2015 6:34 AM
    Moderator
  • Hello Herro wong,

    Thanks for the reply,

    I tried your solution but it didn't work, posting entire method with little modification below.

          public static async Task<HttpResponseMessage> UploadFile(Stream fileStream, string fileName,....,CancellationToken cancellationToken)
            {
               
                HttpClient httpClient = null;
                HttpResponseMessage response = null;
    
    
                try
                {
    
                    httpClient = new HttpClient();
    
                    MultipartFormDataContent form = new MultipartFormDataContent();
              
                  
                    if (fileStream != null)
                        form.Add(new StreamContent(fileStream), "somestring", fileName);
    
     
    
                    var httprequestMessage = new HttpRequestMessage(HttpMethod.Post, postURL);
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("user-agent", ConfigManager.UserAgent);
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html, application/xhtml+xml, */* ");
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
                    httprequestMessage.Content = form;
                   
    
                    response = await httpClient.SendAsync(httprequestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
    
                    response.EnsureSuccessStatusCode();
    
                 
                }
                catch (Exception ex)
                {
                  
                }
    
                return response;
            }
    
    

    Tuesday, February 10, 2015 1:03 PM
  • Please can somebody suggest what am I doing wrong in the code. It's urgent.

    Thanks in advance.

    Wednesday, February 11, 2015 6:55 AM
  • Hi Zee_patel,

    From your description, you are uploading file to server, encounter encoding issue when filename contains Unicode. Is it right? I would like to build test environment for this issue. Can you post a mini repro project contains server side? Use your OneDrive and share a link here. I will look into it and let you know the result.

    If i misunderstand, please post more information to make your issue clear.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    Wednesday, February 11, 2015 9:49 AM
    Moderator
  • Hello Herro Wong,

    Thanks for the reply, It's not server side issue, it is issue from client side in encoding filename properly to UTF-8, here is the request of MultipartFormDataContent  that is send to server, which I captured using fiddler.

    --boundary
    Content-Dis-data; name=somestring; filename="=?utf-8?B?QmF5ZXJuIE3DvG5jaGVuLnR4dA==?="; filename*=utf-8''Bayern%20M%C3%BCnchen.txt

    Let me know if you still want more information, I will try to make a demo sample if possible .






    • Edited by zee_patel Wednesday, February 11, 2015 1:36 PM
    Wednesday, February 11, 2015 1:31 PM
  • Hi Zee_patel,

    Yes, it would be better if I can get the repro project and test on my side.

    A work around you can test first. Encode the Unicode file name in client first, post to server and then decode it on server side. To see if the problem persist.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    Monday, February 16, 2015 9:03 AM
    Moderator
  • Hello Herro wong,

    Thanks for the reply,

    As I said earlier, problem was on client side not on server side, finally I found the solution to fix it.

    Below is the code if anybody wants to refer(Not production ready)

     public static async Task<HttpResponseMessage> UploadFile(Stream fileStream, string fileName,....,CancellationToken cancellationToken)
            {
               
                HttpClient httpClient = null;
                HttpResponseMessage response = null;
    
    
                try
                {
    
                    httpClient = new HttpClient();
    
                    MultipartFormDataContent form = new MultipartFormDataContent();
              
    		 string formDataBoundary = "---------------------------2156852217421";
                  
                    if (fileStream != null)
                          form.Add(new StreamContent(
                                        BuildMultipartStream("someString", fileName, fileBytes , formDataBoundary)));
    
    
    
                    var httprequestMessage = new HttpRequestMessage(HttpMethod.Post, postURL);
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("user-agent", ConfigManager.UserAgent);
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html, application/xhtml+xml, */* ");
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
                    httprequestMessage.Content = form;
                    httprequestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
                    httprequestMessage.Content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue(
                        "boundary",
                        formDataBoundary));
    
                   
    
                    response = await httpClient.SendAsync(httprequestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
    
                    response.EnsureSuccessStatusCode();
    
                 
                }
                catch (Exception ex)
                {
                  
                }
    
                return response;
            }
    

       private static Stream BuildMultipartStream(string name, string fileName, byte[] fileBytes, string boundary)
            {
                // Create multipart/form-data headers.
                byte[] firstBytes = Encoding.UTF8.GetBytes(String.Format(
                    "--{0}\r\n" +
                    "Content-Dis-data; name=\"{1}\"; filename=\"{2}\"\r\n" +
                    "\r\n",
                    boundary,
                    name,
                    fileName));
    
                byte[] lastBytes = Encoding.UTF8.GetBytes(String.Format(
                    "\r\n" +
                    "--{0}--\r\n",
                    boundary));
    
                int contentLength = firstBytes.Length + fileBytes.Length + lastBytes.Length;
                byte[] contentBytes = new byte[contentLength];
    
    
                // Join the 3 arrays into 1.
                Array.Copy(
                    firstBytes,
                    0,
                    contentBytes,
                    0,
                    firstBytes.Length);
                Array.Copy(
                    fileBytes,
                    0,
                    contentBytes,
                    firstBytes.Length,
                    fileBytes.Length);
                Array.Copy(
                    lastBytes,
                    0,
                    contentBytes,
                    firstBytes.Length + fileBytes.Length,
                    lastBytes.Length);
    
                return new MemoryStream(contentBytes);
            }

    Wednesday, February 18, 2015 1:14 PM