AガイドからASP.NETWebAPIRTMでの非同期ファイルアップロードに適合したPOSTASP.NetWebApiメソッドがあります。
最初のリクエストが実行されて完了した後にすべてのリクエストが実行されるという、障害のあるタスクの問題が発生しています。
シナリオは次のとおりです。ファイルを他のパラメーターとともにWebAPIPostメソッドにPOSTするサンプルページがあります。初めて正常に動作し、ファイルがアップロードされます。ただし、後続のすべての要求は、タスクを障害状態で終了します。「MIMEマルチパートストリームの予期しない終了が発生します。MIMEマルチパートメッセージは完全ではありません。」なぜ何かアイデアはありますか?
以下に貼り付けたのは、Postメソッドのソースコード、サンプルhtmlフォーム、およびAggregateExceptionです。
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;
}
次のようなサンプルフォームを使用して、このWebAPIを起動しています。
<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,
t.Exception));
}
return Request.CreateResponse(HttpStatusCode.OK, new MyModel());
});
しかし、これは非常に気質のあるコードです。動作する場合と動作しない場合があります。つまり、問題を完全に解決するわけではありません。