web-dev-qa-db-ja.com

HttpContextがHttpExceptionをスローする

カスタムhttpハンドラーを作成しました。私は、IHttphandlerを実装するクラスを作成してこれを行いました。

そのクラスの中に私はこのようなコードを持っています、

context.Response.Clear();
context.Response.ClearHeaders();
context.Response.AddHeader("Content-Disposition", "attachment;filename=" + attachmentFileName);
context.Response.AddHeader("Content-Length", new FileInfo(downloadFile).Length.ToString());
context.Response.ContentType = GetMimeType(attachmentFileName);
context.Response.TransmitFile(downloadFile);
context.Response.Flush();
context.Response.Close();

時々私はこのようなエラーを受け取ります、

Exception HttpException The remote Host closed the connection The error code is 0x800703E3

またはこれ、

Exception HttpException The remote Host closed the connection The error code is 0x80070040

どちらの場合も、スタックトレースはこれです。

at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect)
at System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush()
at System.Web.HttpResponse.Flush(Boolean finalFlush)
at System.Web.HttpResponse.Flush()

これは本番環境で発生し、過去数日間を振り返ると、エラーが23回発生し、合計で上記のコードが497回呼び出されています。

この失敗は、ユーザーがリンクをクリックして上記のコードを複数回開始し(複数のダウンロードダイアログが表示される)、一部のユーザーがキャンセルしたことに関連していると思います。それがそのようなものであるならば、私は接続が両端で優雅に閉じることを期待したであろうと言っていました。

このエラーの正確な原因をどのように証明できますか?私はこのように.NETトレースを有効にしようとしました なぜリスナーがカスタムハンドラトラフィックをログに記録しないのですか? それを機能させることができませんでした。

しかし、私が見つけたのは、失敗した要求をログに記録するためにIISトレースを有効にしたことです。失敗が再び発生し、そのログにはNOTHINGがありました。

たとえば、他に有効にできるトレースはありますか?

次に試したのはこれです。

if (context.Response.IsClientConnected)
{
    context.Response.Flush();
    context.Response.Close();
}
else
{
    LogMessage("Client has disconnected before flush was called", Severity.Information);
}

しかし、それでも違いはありませんでした。私が推測する理由は、フラッシュが呼び出される前ではなく、ダウンロードの実行中にクライアントが切断されたためです。

20
peter

Flush()Close()の両方の呼び出しを削除します。あなたは本当にそれらを必要としません。ハンドラーが完了すると、ハンドラーは終了し、ASP.NETが要求のクローズを処理します。

さらに、Flush()は、コンテンツをクライアントにストリーミングするときに使用する必要があります(ブロックで応答ストリームにパーツを追加します)。 TransmitFile()で使用する必要はありません。

14
Samuel Neff

私は同様の問題に遭遇し、Response.End()は回避する必要があることを説明し、代わりにCompleteRequest()メソッドの使用を提案するこの記事を入手しました。 MSDNのドキュメントもこの情報で更新されています。これが誰かの役に立つことを願っています。

http://blogs.msdn.com/b/aspnetue/archive/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn- documentation.aspx

8
DotNetUser

Response.End()の代わりにResponse.Flush()を使用します

Response.End()のソースコードは次のようになります。

public void End()
{
    if (this._context.IsInCancellablePeriod)
    {
        InternalSecurityPermissions.ControlThread.Assert();
        Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
    }
    else if (!this._flushing)
    {
        this.Flush();
        this._ended = true;
        if (this._context.ApplicationInstance != null)
        {
            this._context.ApplicationInstance.CompleteRequest();
        }
    }
}
4
smartcaveman

どの.NETフレームワークを使用していますか?このフォーラムスレッド here は、クライアントの切断に特に関連するIIS7と.NET2.0を使用した同様の問題について説明しています。この問題は、.NET Framework 3.5で対処されました。

実際のエラーコードは

0x800703E3 "The I/O operation has been aborted because of either a thread exit or an application request."
2
Dan

web設定の最大サイズファイルをより大きなファイルに設定してみてください。

MaxRequestLength(KB単位)を設定できます

iisのアプリプールを頻繁にリサイクルしないようにしてください。

1
jack.the.ripper

この例外の詳細については、 http://support.Microsoft.com/kb/97745 にアクセスしてください。

1
Sooraj

私は時々エラーがあります:

Exception message: An error occurred while communicating with the remote Host. The error code is 0x80070057.

本番ではランダムです。開発やQAでは再現されません。

このソリューションを適用します。 Response.IsClientConnected エラーが修正されることを願っています。

ソース:

https://stackoverflow.com/a/11441375/1536197

0