Velvet Star Monitor

Standout celebrity highlights with iconic style.

general

HttpClient: The uri string is too long

Writer Matthew Harrington

Given the following attempt to post data to a web service that generates PDF files, PDF rocket (which is awesome by the way).

I get the error Invalid URI: The uri string is too long
Why would anyone impose an arbitrary limit on POSTed data?

using (var client = new HttpClient())
{ // Build the conversion options var options = new Dictionary<string, string> { { "value", html }, { "apikey", ConfigurationManager.AppSettings["pdf:key"] }, { "MarginLeft", "10" }, { "MarginRight", "10" } }; // THIS LINE RAISES THE EXCEPTION var content = new FormUrlEncodedContent(options); var response = await client.PostAsync("", content); var result = await response.Content.ReadAsByteArrayAsync(); return result;
}

I receive this rediculous error.

 {System.UriFormatException: Invalid URI: The Uri string is too long. at System.UriHelper.EscapeString at System.Uri.EscapeDataString at System.Net.Http.FormUrlEncodedContent.Encode at System.Net.Http.FormUrlEncodedContent.GetContentByteArray

This reminds me of 640k ought to be enough... I mean really?

6

4 Answers

If, like me, you're faced with some wonky 3rd party web service that will only accept form content, you can work around the problem like this:

// Let's assume you've got your key-value pairs organised into a nice Dictionary<string, string> called formData
var encodedItems = formData.Select(i => WebUtility.UrlEncode(i.Key) + "=" + WebUtility.UrlEncode(i.Value));
var encodedContent = new StringContent(String.Join("&", encodedItems), null, "application/x-www-form-urlencoded");
// Post away!
var response = await client.PostAsync(url, encodedContent);
2

With a post can include the content in the http message instead of the URI. A uri has a max length of 2083 characters. You could send it as JSON in the http message instead of the URI which is the recommended way to send larger chunks of data in an HttpPost/HttpPut. I altered your code to make use of it. This assumes that your service you are contacting can work with JSON (.net Web Api out of the box should have no problem with this).

using (var client = new HttpClient())
{ // Build the conversion options var options = new { value = html, apikey = ConfigurationManager.AppSettings["pdf:key"], MarginLeft = "10", MarginRight = "10" }; // Serialize our concrete class into a JSON String var stringPayload = JsonConvert.SerializeObject(options); var content = new StringContent(stringPayload, Encoding.UTF8, "application/json"); var response = await client.PostAsync("", content); var result = await response.Content.ReadAsByteArrayAsync(); return result;
}

Make sure to install newtonsoft json.

7

I just solved a similar problem. For me I was integrating with a backend I didn't control and had to POST file along with form data (eg customerID) as form variables. So switching to JSON or Multipart would break the backend I didn't control. The problem was that large files would cause the FormUrlEncodedContent to throw an error saying "The uri string is too long".

This is the code that solved it for me after two days of effort (note still needs to be tweaked to be ASYNC).

private string UploadFile(string filename, int CustomerID, byte[] ImageData) { string Base64String = "data:image/jpeg;base64," + Convert.ToBase64String(ImageData, 0, ImageData.Length); var baseAddress = new Uri("[PUT URL HERE]"); var cookieContainer = new CookieContainer(); using (var handler = new HttpClientHandler() { AllowAutoRedirect = true, UseCookies = true, CookieContainer = cookieContainer }) using (var client = new HttpClient(handler) { BaseAddress = baseAddress }) { try { //ENCODE THE FORM VARIABLES DIRECTLY INTO A STRING rather than using a FormUrlEncodedContent type which has a limit on its size. string FormStuff = string.Format("name={0}&file={1}&id={2}", filename, HttpUtility.UrlEncode(Base64String), CustomerID.ToString()); //THEN USE THIS STRING TO CREATE A NEW STRINGCONTENT WHICH TAKES A PARAMETER WHICH WILL FormURLEncode IT AND DOES NOT SEEM TO THROW THE SIZE ERROR StringContent content = new StringContent(FormStuff, Encoding.UTF8, "application/x-www-form-urlencoded"); //UPLOAD string url = string.Format("/ajax/customer_image_upload.php"); response = client.PostAsync(url, content).Result; return response.Content.ToString(); } catch (Exception ex) { return ex.ToString(); } } }
0

@Mick Byrne : Thanks - your solution worked like a charme!

Here is my complete code:

 public async Task DateienSendenAsync (string PfadUndDatei, string Dateiname, String VRPinGUID, String ProjektGUID, String VRPinX, String VRPinY, String VRPinZ) { var client = new HttpClient(); // Create the HttpContent for the form to be posted. var requestContent = new[] { new KeyValuePair<string, string>("dateiname", Dateiname), new KeyValuePair<string, string>("bild", Convert.ToBase64String(File.ReadAllBytes(PfadUndDatei))), new KeyValuePair<string, string>("VRPinGUID", VRPinGUID), new KeyValuePair<string, string>("ProjektGUID", ProjektGUID), new KeyValuePair<string, string>("ebene", "ebene"), new KeyValuePair<string, string>("raumnummer", "raumnummer"), new KeyValuePair<string, string>("ansichtsname", "ansichtsname"), new KeyValuePair<string, string>("VRPinX", VRPinX), new KeyValuePair<string, string>("VRPinY", VRPinY), new KeyValuePair<string, string>("VRPinZ", VRPinZ), }; String url = ""; var encodedItems = requestContent.Select(i => WebUtility.UrlEncode(i.Key) + "=" + WebUtility.UrlEncode(i.Value)); var encodedContent = new StringContent(String.Join("&", encodedItems), null, "application/x-www-form-urlencoded"); // Post away! var response = await client.PostAsync(url, encodedContent); }

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy