我有一个改编自
A guide to asynchronous file uploads in ASP.NET Web API RTM的POST ASP.Net Web Api方法.
我遇到了故障的任务问题,在第一个请求被触发并完成后触发了所有请求.
这是场景:我有一个示例页面,它将文件和其他参数一起发布到Web API Post方法.它第一次正常工作,文件上传.但是,所有后续请求都会在故障状态下结束任务.我得到“MIME多部分流的意外结束. MIME多部分消息不完整.“任何想法为什么?
下面粘贴的是我的Post方法的源代码,示例html表单和Aggregate Exception.
public Task<HttpResponseMessage> Post([FromUri]string memberNumber) { // Check if the request contains multipart/form-data. if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } string root = HttpContext.Current.Server.MapPath("~/App_Data"); var provider = new MultipartFormDataStreamProvider(root); // Read the form data and return an async task. var task = Request.Content.ReadAsMultipartAsync(provider). ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.InternalServerError,t.Exception)); } return Request.CreateResponse(HttpStatusCode.OK,new MyModel()); }); return task; }
我正在使用这样的示例表单解雇此web api:
<form name="form1" method="post" enctype="multipart/form-data" action="api/claims/asd123" style="margin:auto;width:500px;"> <div> <label for="HCPracticeNumber">HC Pratice Number:</label> <input type="text" name="HCPracticeNumber" id="HCPracticeNumber"/> </div> <div> <label for="ServiceDate">Service/Treatment date:</label> <input type="text" name="ServiceDate" id="ServiceDate"/> </div> <div> <label for="AmountClaimed">Amount Claimed:</label> <input type="text" name="AmountClaimed" id="AmountClaimed"/> </div> <div> <label for="Image">Image Attachment:</label> <input name="Image" type="file" /> </div> <div> <input type="submit" value="Submit" /> </div> </form>
返回的AggregateException如下:
<Error> <Message>An error has occurred.</Message> <ExceptionMessage>One or more errors occurred.</ExceptionMessage> <ExceptionType>System.AggregateException</ExceptionType> <StackTrace/> <InnerException> <Message>An error has occurred.</Message> <ExceptionMessage> Unexpected end of MIME multipart stream. MIME multipart message is not complete. </ExceptionMessage> <ExceptionType>System.IO.IOException</ExceptionType> <StackTrace> at System.Net.Http.Formatting.Parsers.MimeMultipartBodyPartParser.<ParseBuffer>d__0.MoveNext() at System.Net.Http.HttpContentMultipartExtensions.MoveNextPart(MultipartAsyncContext context) </StackTrace> </InnerException> </Error>
更新:
在Filip在他的博客网站上提出建议后,我修改了post方法,将流位置重置为0,如下所示:
Stream reqStream = Request.Content.ReadAsStreamAsync().Result; if (reqStream.CanSeek) { reqStream.Position = 0; } var task = Request.Content.ReadAsMultipartAsync(provider). ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { throw new HttpResponseException( Request.CreateErrorResponse(HttpStatusCode.InternalServerError,new MyModel()); });
解决方法
事实证明,正如Filip在评论中所建议的那样,我从
Implementing Message Handlers To Track Your ASP .net Web API Usage改编的Web API使用处理程序正在读取内容正文,因此在我的POST方法中处理请求时,会在流上找到位置搜索器.
因此,如果请求的类型为IsMimeMultipartContent,我向WebApiUsageHandler添加了一个条件语句,以便不读取请求主体.这解决了这个问题.
更新
我想用Filip通过电子邮件向我建议的另一个选项更新答案,以便记录:
如果您在API使用处理程序中使用此代码,则在读取正文之前:
//read content into a buffer request.Content.LoadIntoBufferAsync().Wait(); request.Content.ReadAsStringAsync().ContinueWith(t => { apiRequest.Content = t.Result; _repo.Add(apiRequest); });
请求将被缓冲,并且可以读取两次,因此可以在管道中进一步上传.希望这可以帮助.