1

IIS 7/7.5 を使用しています。ユーザーが巨大なデータをアップロードできるページがあります。POST 本文を読む必要がある場合とそうでない場合があります。IIS/ASP.NET で、通知するまで POST エンティティ本体の読み取りを延期する方法はありますか。

4

1 に答える 1

3

ファイル サイズを気にせずに、リクエスト ヘッダーを安全に読み取ることができます。詳しく説明しましょう。/upload.aspxエンドポイントにファイルをアップロードできる次の html ページを検討してください。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <form action="/upload.ashx" method="post" enctype="multipart/form-data">
        <input type="file" name="file" />
        <button type="submit">OK</button>
    </form>
</body>
</html>

次に、汎用ハンドラーを作成できます。

public class Upload: IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        var request = context.Request;
        var response = context.Response;
        response.ContentType = "text/plain";
        response.Write(request.Headers.ToString());
    }

    public bool IsReusable
    {
        get { return true; }
    }
}

次に、巨大なファイルをアップロードできるようにするために、web.config で要求の制限を増やしたことを確認します。

<httpRuntime maxRequestLength="10485760" />

と:

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="1073741824" />
      </requestFiltering>
    </security>
</system.webServer>

ここで、ユーザーがアップロードする非常に大きなファイル (たとえば 5GB) を選択し、送信ボタンを押したとします。汎用ハンドラーのProcessRequestメソッドはすぐにヒットするため、ヘッダーに非常にすばやくアクセスできます。

public void ProcessRequest(HttpContext context)
{
    var fileSize = context.Request.ContentLength;
}

このファイルの内容を読みたい場合は、ファイルの入力ストリームから読み始めることができます。これは、ファイル全体がアップロードされるまで明らかに時間がかかります。

public void ProcessRequest(HttpContext context)
{
    // We reach at that point pretty fast and we can read the headers here
    // and determine for example the total bytes to be uploaded
    var fileSize = context.Request.ContentLength;

    // now we can start reading the file which would obviously take quite a lot of time:
    context.Request.Files[0].InputStream.Read(...)
}

しかし、あなたは自問するかもしれません:ProcessRequestメソッドは、ユーザーが送信ボタンを押した直後にヒットします。その時点でアップロードされたファイルはどこにありますか? 実際、クライアントからバイトが到着すると、IIS はそれらを一時ファイルにチャンクし (メモリ内にないため、心配する必要はありません)、InputStream はこの場所を指しているため、そこから読み取りを開始すると、実際にはIIS がクライアントから既に受信し、利用できるようにしたデータを読み取ります。これらの一時ファイルは、入力ストリームからの読み取りを開始するときに作成されます。このストリームから読み取るときは、データをメモリにロードしているため、注意が必要です。したがって、クライアントから非常に大きなデータが送られる可能性がある場合は、常にチャンクで読み取って処理する必要があります。Stream.CopyTo方法)。

于 2013-03-02T14:11:09.930 に答える