ASP.NETのチュートリアルに従って、次のような非同期ファイルのアップロードを行うためのWeb APIコントローラーメソッドを実装しました。
public Task<HttpResponseMessage> PostFormData()
{
// 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<HttpResponseMessage>(t =>
{
if (t.IsFaulted || t.IsCanceled)
{
Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
}
return Request.CreateResponse(HttpStatusCode.OK);
});
return task;
}
標準のマルチパートHTMLフォームを介したファイルのアップロードは完全に機能します。ただし、別の開発者がFlexのFileReferenceクラスによって構築されたマルチパートフォームを介してファイルをアップロードしようとすると、エラーがスローされます。
MIMEマルチパートストリームの予期しない終了。 MIMEマルチパートメッセージは完全ではありません。
問題がWeb APIにあるのかFlexにあるのかわかりません。影響のない関連修正がいくつか見つかりました( Multipart form POST using ASP.Net Web API )、最近ではこの修正( 「MIMEマルチパートストリーム。MIMEマルチパートメッセージは完了していません」webapiアップロードのエラー )。 5月、Nugetからの最新リリースは8月だったため、この修正プログラムは既に展開されており、私の問題の根本原因ではないと思います。
既存の調査を読んで、codeplexの問題を追跡すると、この問題が9月にも存在することが他の誰かによって確認されたようです。
彼らは、MVC 4が「\ r\n」で終了せずにアップロードの解析に失敗すると信じています。
この問題は本当に単純ですが、修正が非常に困難です。問題は、UploadifyがMultiPartFormメッセージの最後に「\ r\n」を追加しないことです。
http://aspnetwebstack.codeplex.com/discussions/354215
Flexのアップロードによって「\ r\n」が追加されることを確認する価値があるかもしれません
フレックスにも同じ問題がありました。そして、以下はそれを解決したコードです。基本的に、カスタムストリームを使用して、asp.net web apiが期待している改行を追加しました。
Stream reqStream = Request.Content.ReadAsStreamAsync().Result;
MemoryStream tempStream = new MemoryStream();
reqStream.CopyTo(tempStream);
tempStream.Seek(0, SeekOrigin.End);
StreamWriter writer = new StreamWriter(tempStream);
writer.WriteLine();
writer.Flush();
tempStream.Position = 0;
StreamContent streamContent = new StreamContent(tempStream);
foreach(var header in Request.Content.Headers)
{
streamContent.Headers.Add(header.Key, header.Value);
}
// Read the form data and return an async task.
await streamContent.ReadAsMultipartAsync(provider);
お役に立てれば。
MVC4でも同じ問題が発生しましたが、入力に名前を追加してください。
<input type="file" id="fileInput" name="fileInput"/>
そして、すべての魔法がバックアップされて動作しています!
グーグルでここに着陸する場合:
MIMEマルチパートストリームの予期しない終了。 MIMEマルチパートメッセージは完全ではありません。
要求ストリームを複数回読み取ると、この例外も発生します。リクエストストリームは1回しか読み取れないことを説明するソースを見つけるまで、何時間も苦労しました。
私の場合、MultipartMemoryStreamProvider
を使用してリクエストストリームを読み取ろうとすると同時に、APIメソッドのパラメーター(リクエストボディから取得)を指定することで、ASP.NETに魔法をかけさせました。
画像ファイルが最初にアップロードされる仮想ディレクトリ(「〜/ App_Data」ディレクトリの例)が物理的に存在することを確認してください。プロジェクトを公開すると、出力ファイルに含まれない場合があります。
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
Postメソッドで設定していたヘッダーを削除しただけで、この問題は解決しました。
問題はこの行です:
string root = HttpContext.Current.Server.MapPath("~/App_Data");
Localhostでのみ動作します。HttpContext.CurrentのようなSystem.Webオブジェクトが使用できないコンテキスト(静的メソッドなどから)の代わりにHostingEnvironment.MapPathを使用できます。
var mappedPath = System.Web.Hosting.HostingEnvironment.MapPath("~/SomePath");
Server.MapPathとHostingEnvironment.MapPathの違いは何ですか? も参照してください。
この回答への参照 サーバーマップパスの実行方法