WebAPI无法解析multipart / form-data帖子

时间:2014-01-06 03:44:52

标签: c# asp.net ios json asp.net-web-api

我正在尝试接受来自客户端(iOS应用)的帖子,而我的代码仍然无法读取流。说消息不完整。我一直试图让这个工作好几个小时似乎我的消息格式有些不对劲。我所要做的就是读取一个字符串,但我正在处理iOS开发人员的开发人员只知道如何发送multipart / form-data而不是content-type json。

这是确切的错误:

  

MIME多部分流的意外结束。 MIME多部分消息不完整。“

此处失败:await Request.Content.ReadAsMultipartAsync(provider);

接头:

POST http://localhost:8603/api/login HTTP/1.1
Host: localhost:8603
Accept-Encoding: gzip,deflate
Content-Type: multipart/form-data; boundary=------------nx-oauth216807
Content-Length: 364
Accept-Language: en-us
Accept: */*
Connection: keep-alive

体:

--------------nx-oauth216807
Content-Disposition: form-data; name="token"

CAAH5su8bZC1IBAC3Qk4aztKzisZCd2Muc3no4BqVUycnZAFSKuleRU7V9uZCbc8DZCedYQTIFKwJbVZCANJCs4ZCZA654PgA22Nei9KiIMLsGbZBaNQugouuLNafNqIOTs9wDvD61ZA6WSTd73AVtFp9tQ1PmFGz601apUGHSimYZCjLfGBo40EBQ5z6eSMNiFeSylym1pK4PCvI17fXCmOcRix4cs96EBl8ZA1opGKVuWizOsS0WZCMiVGvT
--------------nx-oauth216807--

以下是WebAPI代码:

    public async Task<HttpResponseMessage> PostFormData()
    {
        // Check if the request contains multipart/form-data.
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }
        try
        {
        string root = HttpContext.Current.Server.MapPath("~/App_Data");
        var provider = new MultipartFormDataStreamProvider(root);

        // Read the form data and return an async task.
        await Request.Content.ReadAsMultipartAsync(provider);

        // This illustrates how to get the file names.
        foreach (MultipartFileData file in provider.FileData)
        {
            Trace.WriteLine(file.Headers.ContentDisposition.FileName);
            Trace.WriteLine("Server file path: " + file.LocalFileName);
        }
        return Request.CreateResponse(HttpStatusCode.OK);

        }
        catch (System.Exception e)
        {
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
        }
    }

6 个答案:

答案 0 :(得分:39)

我的应用程序也会定期遇到此错误。升级到WEB API 2.1什么也没做,异常消息完全没用。

我认为实际发生的事情是它在大文件上窒息。在web.config中增加我的最大请求限制似乎可以解决它。

<system.web>
    <httpRuntime maxRequestLength="30000" />
</system.web>

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="30000" />
      </requestFiltering>
    </security>
</system.webServer>

(这会将天花板设置为30 megs。将其设置为您需要的任何内容。更多信息here

答案 1 :(得分:11)

我也遇到了这个错误。 InnerExceptionCannot access a disposed object.这意味着在您致电ReadAsMultipartAsync之前,有些内容正在播放您的信息流。
在此电话Request.Content.ReadAsMultipartAsync(provider)之前的某个地方,您可以致电 Request.Content.LoadIntoBufferAsync().Wait(),它会将此tream加载到缓冲区中,并允许您多次读取它 这不是最佳解决方案,但可行。

答案 2 :(得分:4)

我要离开这里,因为我花了很长时间尝试其他解决方法,直到我碰到以下有用的答案,有些人遇到这个问题可能会在这篇帖子上结束。

需要在请求内容流的末尾附加一个\ r \ n。

而不是使用此行来读取数据:

await Request.Content.ReadAsMultipartAsync(provider);

您需要:

  1. 将请求流加载到内存

  2. 附加所需的\ r \ n字符串

  3. 从内存内容

  4. 创建流内容
  5. 手动将请求标头添加到流内容

  6. 最后改用:

    streamContent.ReadAsMultipartAsync(provider); 
    
  7. 在这里查看Landuber Kassa的答案以获取完整的代码:ASP.NET Web API, unexpected end of MIME multi-part stream when uploading from Flex FileReference

答案 3 :(得分:2)

如果有人想要使用它,只需修改Shaw Levin的答案。

boundary = value.Substring(0, value.IndexOf("\r\n"));将找到CRLF的第一次出现,您应该将其更改为boundary = value.Substring(0, value.LastIndexOf("\r\n"));,以便查找最后一次出现。否则,如果内容在中间某处包含CRLF,则会丢失请求中的部分数据。

答案 4 :(得分:1)

有类似的错误帖子,对于一些人来说,解决方案是:提到Id =&#34;&#34;,name =&#34;&#34;属于文件上传html控件,感谢WebAPI upload error. Expected end of MIME multipart stream. MIME multipart message is not complete

但在我的情况下,它没有解决上述简单的调整:(

答案 5 :(得分:1)

我不推荐这个答案 - 希望现在有更好的方法。

有人问这是我的自定义解析器,它一直运行良好:

边界来自这里:

        string value;
        using (var reader = new StreamReader(tempStream, Encoding.UTF8))
        {
            value = reader.ReadToEnd();
            // Do something with the value
        }

        boundary = value.Substring(0, value.IndexOf("\r\n"));

然后我们在这里解析请求的内容:

   public Dictionary<string, BodyContent> ParseContent(string content)
    {
        string[] list = content.Split(new string[] { boundary }, StringSplitOptions.RemoveEmptyEntries);
        string name="", val="";
        Dictionary<string, BodyContent> temp = new Dictionary<string, BodyContent>();
        foreach (String s in list)
        {
            if (s == "--" || s == "--\r\n")
            {
                //Do nothing.
            }
            else
            {
                string[] token = s.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                val = "";
                name = "";
                foreach (string x in token)
                {

                    if(x.StartsWith("Content-Disposition"))
                    {
                        //Name
                        name = x.Substring(x.IndexOf("name=")+5, x.Length - x.IndexOf("name=")-5);
                        name = name.Replace(@"\","");
                        name = name.Replace("\"","");
                    }
                    if (x.StartsWith("--"))
                    {
                        break;
                    }
                    if (!x.StartsWith("--") && !x.StartsWith("Content-Disposition"))
                    {
                        val = x;
                    }

                }
                if (name.Length > 0)
                {
                    BodyContent b = new BodyContent();
                    b.content = name;
                    if (val.Length == 0)
                    {
                        b.value = "";
                    }
                    else
                    {
                        b.value = val;
                    }
                    temp.Add(name, b);
                }
            }

        }
        return temp;        
    }
相关问题