5

I am trying to do a POST like this:

    HttpClient hc = new HttpClient();
    byte[] bytes = ReadFile(@"my_path");

    var postData = new List<KeyValuePair<string, string>>();
    postData.Add(new KeyValuePair<string, string>("FileName", "001.jpeg"));
    postData.Add(new KeyValuePair<string, string>("ConvertToExtension", ".pdf"));
    postData.Add(new KeyValuePair<string, string>("Content", Convert.ToBase64String(bytes)));

    HttpContent content = new FormUrlEncodedContent(postData);
    hc.PostAsync("url", content).ContinueWith((postTask) => {
    postTask.Result.EnsureSuccessStatusCode();
    });

but I receive this exception:

Invalid URI: The Uri string is too long.

complaining about this line: HttpContent content = new FormUrlEncodedContent(postData);. For small files it works but I don't understand why for larger ones it doesn't?

When I do POST the content can be larger...Then why it complains about URI?

j0k
  • 22,600
  • 28
  • 79
  • 90
Cristian Boariu
  • 9,603
  • 14
  • 91
  • 162

2 Answers2

5

You should use MultipartFormDataContent ( http://msdn.microsoft.com/en-us/library/system.net.http.multipartformdatacontent%28v=vs.110%29 ) instead of FormUrlEncodedContent, which sends your data as "application/x-www-form-urlencoded".

So even if your using the POST verb, it is still POSTing to a very long url containing your data, hence the error.

The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.

See : http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1

For a sample, have a look at this answer : ASP.NET WebApi: how to perform a multipart post with file upload using WebApi HttpClient

Community
  • 1
  • 1
mathieu
  • 30,974
  • 4
  • 64
  • 90
  • Thanks! Do you have any example how to do this? Is this correct? `MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent(); multipartFormDataContent.Add(new FormUrlEncodedContent(postData));` – Cristian Boariu Aug 15 '12 at 09:01
  • @CristianBoariu Updated my answer to link a sample – mathieu Aug 15 '12 at 09:30
  • 1
    @mathieu that example still throw the Exception, since the FormUrlEncodedContent is build – Felipe Pessoto Oct 25 '12 at 12:36
0

I know this has already been answered, but I ran into this same issue and found that is is a limitation in the FormUrlEncodedContent class. The reason for the error is that the encoding of the objects is being handled by the Uri.EscapeDataString(). This post explains it on CodePlex. I ended up coming up with my own solution to Url Encode using the HTTPUtility class instead.

using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Web;

namespace Wfm.Net.Http
{
    public class UrlContent : ByteArrayContent
    {
        public UrlContent(IEnumerable<KeyValuePair<string, string>> content)
            : base(GetCollectionBytes(content, Encoding.UTF8))
        {
        }

        public UrlContent(byte[] content, int offset, int count) : base(content, offset, count)
        {
        }

        private static byte[] GetCollectionBytes(IEnumerable<KeyValuePair<string, string>> c, Encoding encoding)
        {
            string str = string.Join("&", c.Select(i => string.Concat(HttpUtility.UrlEncode(i.Key), '=', HttpUtility.UrlEncode(i.Value))).ToArray());
            return encoding.GetBytes(str);
        }
    }


}

I wrote a small article on how I implemented it. Hope this helps anyone with the same issues.

DDiVita
  • 4,225
  • 5
  • 63
  • 117