web-dev-qa-db-ja.com

ASP.NET Web API、Flex FileReferenceからアップロードするときのMIMEマルチパートストリームの予期しない終了

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月だったため、この修正プログラムは既に展開されており、私の問題の根本原因ではないと思います。

25
heyseuss

既存の調査を読んで、codeplexの問題を追跡すると、この問題が9月にも存在することが他の誰かによって確認されたようです。

彼らは、MVC 4が「\ r\n」で終了せずにアップロードの解析に失敗すると信じています。

この問題は本当に単純ですが、修正が非常に困難です。問題は、UploadifyがMultiPartFormメッセージの最後に「\ r\n」を追加しないことです。

http://aspnetwebstack.codeplex.com/discussions/354215

Flexのアップロードによって「\ r\n」が追加されることを確認する価値があるかもしれません

7
Mark Jones

フレックスにも同じ問題がありました。そして、以下はそれを解決したコードです。基本的に、カスタムストリームを使用して、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);

お役に立てれば。

35
Landuber Kassa

MVC4でも同じ問題が発生しましたが、入力に名前を追加してください。

<input type="file" id="fileInput" name="fileInput"/>

そして、すべての魔法がバックアップされて動作しています!

33
Greg Sipes

グーグルでここに着陸する場合:

MIMEマルチパートストリームの予期しない終了。 MIMEマルチパートメッセージは完全ではありません。

要求ストリームを複数回読み取ると、この例外も発生します。リクエストストリームは1回しか読み取れないことを説明するソースを見つけるまで、何時間も苦労しました。

私の場合、MultipartMemoryStreamProviderを使用してリクエストストリームを読み取ろうとすると同時に、APIメソッドのパラメーター(リクエストボディから取得)を指定することで、ASP.NETに魔法をかけさせました。

8

画像ファイルが最初にアップロードされる仮想ディレクトリ(「〜/ App_Data」ディレクトリの例)が物理的に存在することを確認してください。プロジェクトを公開すると、出力ファイルに含まれない場合があります。

string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
3
Sevda Ersezer

Postメソッドで設定していたヘッダーを削除しただけで、この問題は解決しました。

1
dk_french032

問題はこの行です:

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の違いは何ですか? も参照してください。

この回答への参照 サーバーマップパスの実行方法

0
Luis Pardo