我正在尝试接受来自客户端(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);
}
}
答案 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)
我也遇到了这个错误。 InnerException
为Cannot access a disposed object.
这意味着在您致电ReadAsMultipartAsync
之前,有些内容正在播放您的信息流。
在此电话Request.Content.ReadAsMultipartAsync(provider)
之前的某个地方,您可以致电
Request.Content.LoadIntoBufferAsync().Wait()
,它会将此tream加载到缓冲区中,并允许您多次读取它
这不是最佳解决方案,但可行。
答案 2 :(得分:4)
我要离开这里,因为我花了很长时间尝试其他解决方法,直到我碰到以下有用的答案,有些人遇到这个问题可能会在这篇帖子上结束。
需要在请求内容流的末尾附加一个\ r \ n。
而不是使用此行来读取数据:
await Request.Content.ReadAsMultipartAsync(provider);
您需要:
将请求流加载到内存
附加所需的\ r \ n字符串
从内存内容
手动将请求标头添加到流内容
最后改用:
streamContent.ReadAsMultipartAsync(provider);
在这里查看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;
}