HttpClient: строка URI слишком длинная

c# dotnet-httpclient

18950 просмотра

4 ответа

6579 Репутация автора

Учитывая следующую попытку отправки данных на веб - сервиса , который создает PDF файлы, PDF ракете ( который является удивительным, кстати ).

Я получаю сообщение об ошибке. Неверный URI: строка URI слишком длинная.
Почему кто-либо может устанавливать произвольное ограничение для POSTданных ed?

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("https://api.html2pdfrocket.com/pdf", content);
    var result = await response.Content.ReadAsByteArrayAsync();
    return result;
}

Я получаю эту смешную ошибку.

 {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

Это напоминает мне о том, что 640kдолжно быть достаточно ... Я имею в виду на самом деле?

Автор: Jim Источник Размещён: 18.07.2016 03:29

Ответы (4)


12 плюса

47046 Репутация автора

Решение

С помощью сообщения можно включить содержимое в сообщение http вместо URI. Максимальная длина URI составляет 2083 символа. Вы можете отправить его как JSON в сообщении http вместо URI, что является рекомендуемым способом отправки больших кусков данных в HttpPost / HttpPut. Я изменил ваш код, чтобы использовать его. Это предполагает, что ваш сервис, с которым вы связываетесь, может работать с JSON (.net Web Api из коробки не должно иметь проблем с этим).

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("https://api.html2pdfrocket.com/pdf", content);
    var result = await response.Content.ReadAsByteArrayAsync();
    return result;
}

Обязательно установите newtonsoft json .

Автор: Igor Размещён: 18.07.2016 03:39

10 плюса

504 Репутация автора

Я только что решил похожую проблему. Для меня я интегрировался с бэкэндом, который я не контролировал и должен был POST-файл вместе с данными формы (например, customerID) в качестве переменных формы. Так что переключение на JSON или Multipart сломало бы бэкэнд, который я не контролировал. Проблема заключалась в том, что большие файлы приводили к тому, что FormUrlEncodedContent выдавал ошибку, говорящую «строка URI слишком длинная».

Это код, который решил его для меня после двух дней усилий (примечание все еще должно быть настроено, чтобы быть 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();
            }



        }

    }
Автор: Brian Размещён: 23.01.2018 03:52

5 плюса

8444 Репутация автора

Если, как и я, вы столкнулись с каким-то непонятным сторонним веб-сервисом, который принимает только содержимое форм, вы можете обойти эту проблему следующим образом:

// 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);
Автор: Mick Byrne Размещён: 15.08.2018 07:07

2 плюса

21 Репутация автора

@ Мик Бирн: Спасибо - ваше решение сработало как шарм!

Вот мой полный код:

      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 = "http://yourhomepage/path/upload.php";

        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);



    }
Автор: Robert Stefanowicz Размещён: 13.10.2018 02:46
Вопросы из категории :
32x32