简体   繁体   English

HttpClient:uri字符串太长

[英]HttpClient: The uri string is too long

Given the following attempt to post data to a web service that generates PDF files, PDF rocket ( which is awesome by the way ). 考虑到以下尝试将数据发布到生成PDF文件的Web服务, PDF火箭顺便说一句真棒 )。

I get the error Invalid URI: The uri string is too long 我收到错误无效的URI:uri字符串太长
Why would anyone impose an arbitrary limit on POST ed data? 为什么有人会对POST数据施加任意限制?

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

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? 这让我想起640k应该就足够了...我的意思是真的吗?

With a post can include the content in the http message instead of the URI. 带有帖子的内容可以包含在http消息中而不是URI中。 A uri has a max length of 2083 characters. uri的最大长度为2083个字符。 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. 您可以在HTTP消息中将其作为JSON而不是URI发送,这是在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). 这假定您正在联系的服务可以使用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;
}

Make sure to install newtonsoft json . 确保安装newtonsoft json

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. 对我来说,我与一个我无法控制的后端集成在一起,不得不将文件以及表单数据(例如customerID)作为表单变量进行发布。 So switching to JSON or Multipart would break the backend I didn't control. 因此,切换到JSON或Multipart会破坏我无法控制的后端。 The problem was that large files would cause the FormUrlEncodedContent to throw an error saying "The uri string is too long". 问题在于大文件会导致FormUrlEncodedContent抛出错误,提示“ uri字符串太长”。

This is the code that solved it for me after two days of effort (note still needs to be tweaked to be ASYNC). 这是经过两天的努力为我解决的代码(请注意,仍然需要调整为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();
            }



        }

    }

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

@Mick Byrne : Thanks - your solution worked like a charme! @Mick Byrne:谢谢-您的解决方案像个魔术师一样工作!

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



    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM