为什么POST会在MVC 4中引发异常?

时间:2012-08-15 08:42:53

标签: asp.net-mvc asp.net-web-api

我正在尝试这样的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);。对于小文件它可以工作,但我不明白为什么对于较大的文件它不?

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

2 个答案:

答案 0 :(得分:4)

您应该使用MultipartFormDataContent(http://msdn.microsoft.com/en-us/library/system.net.http.multipartformdatacontent%28v=vs.110%29)而不是FormUrlEncodedContent,它将您的数据发送为“application / x-www-form-urlencoded”。

因此,即使您使用POST动词,它仍然会发送到包含您的数据的非常长的URL,因此错误。

  

内容类型“application / x-www-form-urlencoded”效率低下   用于发送大量二进制数据或包含的文本   非ASCII字符。内容类型“multipart / form-data”应该是   用于提交包含文件,非ASCII数据和表单的表单   二进制数据。

请参阅:http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1

有关示例,请查看以下答案:ASP.NET WebApi: how to perform a multipart post with file upload using WebApi HttpClient

答案 1 :(得分:0)

我知道这已经得到了解答,但我遇到了同样的问题,发现这是FormUrlEncodedContent类的限制。出错的原因是Uri.EscapeDataString()正在处理对象的编码。 This post explains it on 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);
        }
    }


}

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