Использование Response.End при форсировании PDF-загрузки

Недавно у нас возникла проблема, когда один из разработчиков изменил строку кода с помощью HttpResponse.End на использование HttpApplication.CompleteRequest, когда принудительно загружал PDF файл следующим образом: qaru.site/info/286921/...

Это привело к тому, что некоторые PDF файлы не загрузились из-за неполадки в пространстве, поэтому код был изменен на использование HttpResponse.End.

Однако, помогая моему коллеге, я проводил некоторые исследования, и я наткнулся на следующий вопрос: Является ли Response.End() считающимся вредным?

Какие ссылки на: https://blogs.msdn.microsoft.com/aspnetue/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation/

Учитывая то, что задокументировано в сообщении в блоге MSDN, похоже, что использование HttpResponse.End - неправильный подход, поэтому мне было интересно, требуется ли это или нужен ли более эффективный подход?

Ответ 1

Вот фактический код из Response.End:

public void End()
{
    if (this._context.IsInCancellablePeriod)
    {
        HttpResponse.AbortCurrentThread();
        return;
    }
    this._endRequiresObservation = true;
    if (!this._flushing)
    {
        this.Flush();
        this._ended = true;
        if (this._context.ApplicationInstance != null)
        {
            this._context.ApplicationInstance.CompleteRequest();
        }
    }
}

ThreadAbortException используется для управления потоком - в основном позволяет использовать Response.End вместо return. Но если вы хорошо разработали свой обработчик, вам может и не понадобится его, например. если после Response.End() нет кода. Как правило, лучше не бросать исключение, если вы можете его избежать, так как он (как и все исключения) приведет к отключению стека и некоторой служебной нагрузке.

Возможно, вы можете написать свою собственную версию Response.End и выбрать и выбрать, какие строки кода выполнять на самом деле, например. возможно, вы хотите сбросить буфер и вызвать CompleteRequest, но вы не хотите генерировать исключение.

Ответ 2

Вот такой подход, который я использовал в прошлом

// Sends all currently buffered output 
HttpContext.Current.Response.Flush(); to the client.

// Gets or sets a value indicating whether to send HTTP content to the client.
HttpContext.Current.Response.SuppressContent = true;

/* Causes ASP.NET to bypass all events and filtering in the HTTP pipeline 
   chain of execution and directly execute the EndRequest event. */
HttpContext.Current.ApplicationInstance.CompleteRequest();