Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of Response.End when forcing PDF Download

We had a problem recently where one of the developers had changed a line of code from using HttpResponse.End to using HttpApplication.CompleteRequest when forcing a PDF to download in a similar fashion to the following: https://stackoverflow.com/a/8590579/3856039

Doing so caused some PDF's to fail to download due to a non-breaking space issue so the code was changed back to using HttpResponse.End.

However, in helping my colleague I was carrying out some research and I came across the following question: Is Response.End() considered harmful?

Which links to: https://blogs.msdn.microsoft.com/aspnetue/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation/

Given what is documented in the MSDN blog post, it sounds like using HttpResponse.End is the wrong approach, so I was wondering if it is even needed or whether there is a better approach?

like image 887
Professor of programming Avatar asked Jul 22 '16 15:07

Professor of programming


1 Answers

Here is the actual code from 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();
        }
    }
}

The ThreadAbortException is used for control of flow-- basically allowing you to use Response.End in place of return. But if you've designed your handler well, you may not need it, e.g. if there is no code after Response.End(). It is generally better not to throw the exception if you can avoid it, since it (like all exceptions) will cause a stack unwind and some performance overhead.

Perhaps you can write your own version of Response.End and pick and choose which lines of code actually execute, e.g. maybe you want to flush the buffer and call CompleteRequest but you don't want to throw the exception.

like image 71
John Wu Avatar answered Oct 11 '22 21:10

John Wu