HttpClient:uri字符串太长

本文关键字:字符串 uri HttpClient | 更新日期: 2023-09-27 17:57:25

考虑到以下将数据发布到生成PDF文件的web服务的尝试,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应该足够了。。。我是说真的吗

HttpClient:uri字符串太长

如果你像我一样,面对一些只接受表单内容的不稳定的第三方web服务,你可以解决这样的问题:

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

使用post可以将内容包含在http消息中,而不是URI中。uri的最大长度为2083个字符。您可以在http消息中以JSON的形式发送它,而不是URI,这是在HttpPost/HttpPut中发送较大数据块的推荐方式。我修改了你的代码以利用它。这假设你正在联系的服务可以使用JSON(.netWebApi开箱即用应该没有问题)。

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。

我刚刚解决了一个类似的问题。对我来说,我正在与一个我无法控制的后端集成,并且必须将文件和表单数据(例如customerID)作为表单变量进行POST。因此,切换到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();
            }

        }
    }

@Mick Byrne:谢谢-你的解决方案很有魅力!

这是我的完整代码:

      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>("answersichtsname", "answersichtsname"),
                            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);

    }