5

我正在尝试做这样的 POST:

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

但我收到了这个例外:

无效的 URI:Uri 字符串太长。

抱怨这条线:HttpContent content = new FormUrlEncodedContent(postData);。对于小文件,它可以工作,但我不明白为什么对于较大的文件它不起作用?

当我发布内容时,内容可能会更大......那为什么它会抱怨 URI?

4

2 回答 2

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

于 2012-08-15T08:48:42.847 回答
0

我知道这已经得到解答,但我遇到了同样的问题,发现这是 FormUrlEncodedContent 类中的一个限制。错误的原因是对象的编码正在由Uri.EscapeDataString(). 这篇文章在 CodePlex 上进行了解释。我最终使用 HTTPUtility 类提出了自己的 Url Encode 解决方案。

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


}

我写了一篇关于我如何实现它的小文章。希望这可以帮助任何有同样问题的人。

于 2014-08-22T13:07:35.470 回答