WebAPI无法parsing多部分/表单数据文章
我试图接受来自客户端(iOS应用程序)的文章,我的代码在阅读stream时一直失败。 说消息不完整。 我一直试图让这个工作几个小时,似乎是我的消息格式或东西是错误的。 所有我想要做的是读取一个string,但我正在与谁在做iOS部分的开发人员只知道如何发送multipart / form-data而不是content-type json。
这是确切的错误:
意外的MIME多部分stream结束。 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); } }
我的应用程序也定期遇到这个错误。 升级到WEB API 2.1没有做任何事情,exception消息是完全无用的。
我觉得实际上发生了什么,但是在大文件上却令人窒息。 在web.config中增加我的最大请求限制似乎解决了它的权利。
<system.web> <httpRuntime maxRequestLength="30000" /> </system.web> <system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="30000" /> </requestFiltering> </security> </system.webServer>
(这将天花板设置为30米,将其设置为任何您需要的。
我也遇到过这个错误。 InnerException
是Cannot access a disposed object.
这意味着在您调用ReadAsMultipartAsync
之前,某些内容正在读取您的stream。
在调用Request.Content.ReadAsMultipartAsync(provider)
之前的某个地方,可以调用Request.Content.LoadIntoBufferAsync().Wait()
,它会将这个stream加载到一个缓冲区中,并允许您多次读取它。
这不是一个最佳的解决scheme,但它的工作原理。
我离开这里,因为我花了相当一段时间尝试其他解决方法,直到我碰到以下有用的答案,并有一些人有这个问题可能最终在这个职位。
需要在请求内容stream的末尾附加一个\ r \ n。
而不是使用这一行来读取数据:
await Request.Content.ReadAsMultipartAsync(provider);
您将需要:
-
将请求stream加载到内存
-
附加所需的\ r \ nstring
-
从内存内容创build一个stream内容
-
手动将请求标头添加到stream内容
-
最后用这个代替:
streamContent.ReadAsMultipartAsync(provider);
在这里查看Landuber Kassa的答案以获得完整的代码: ASP.NET Web API,从Flex FileReference上传时MIME多部分stream的意外结束
如果有人想使用它,只需修改Shaw Levin的答案即可。
boundary = value.Substring(0, value.IndexOf("\r\n"));
会发现CRLF的第一个出现,你应该改变它为boundary = value.Substring(0, value.LastIndexOf("\r\n"));
所以它寻找最后的发生。 否则,如果内容中包含CRLF,则会丢失请求中的部分数据。
有类似的错误的post,对于一些,解决scheme的工作是:提到Id =“”,名称=“”属性file uploadHTML控制,感谢WebAPI上传错误。 预期结束的MIME多部分stream。 MIME多部分邮件不完整
但在我的情况下,它没有解决上面的简单调整:(
我不会推荐这个答案 – 希望现在有更好的方法。
有人问,所以这里是我的自定义分析器一直工作正常:
边界来自这里:
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"));
然后我们在这里parsing请求的内容:
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; }
- 在iOS中使用AVAudioPlayer之后,请讲话录音机失败
- UINavigationController interactivePopGestureRecognizer在iOS7中工作exception
- 使用Swift UIApplication子类的Objective-C项目。 错误:类未加载
- 在Objective-C中返回一个types为id的2D C数组
- MonoGame – BlendState – 2D SpriteBatch
- 查看方向更改
- 在iPhone 5s以上的设备上,CAShapeLayer不会随CGAffineTransformRotate旋转
- 文件自预编译头build立以来已被修改
- 总是在iOS 7中获得唯一的设备ID