1

I have the following code in my MVC C# application:

      return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "PSL.xlsx"); 

which returns a PSL file from a stream. I am trying to do the same thing in my Web Forms code behind with:

            Response.Clear();
            Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            Response.AddHeader("Content-Disposition", "attachment; filename=PSL.xlsx");
            Response.BinaryWrite(stream.ToArray());
            // myMemoryStream.WriteTo(Response.OutputStream); //works too
            Response.Flush();
            Response.Close();
            Response.End();

Wanted to know if this is the right approach as I am getting the following error message:

  Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}
Nate Pet
  • 44,246
  • 124
  • 269
  • 414
  • This looks OK to me. Where are you getting this error? Which line exactly? – HaukurHaf Dec 29 '16 at 20:51
  • Right after it runs. I have the code in a method that returns void. Are these 2 identical codes (The one from MVC vs the one in Web Forms?) – Nate Pet Dec 29 '16 at 20:55
  • It's not the exact same code but the result should be the same. Set some headers and then output the binary data to the browser. This error message does not make sense to me. I don't get which expression is being evaluated. – HaukurHaf Dec 29 '16 at 20:59
  • Are you using it inside UpdatePanel? – Win Dec 29 '16 at 21:02

1 Answers1

4

The error is caused by a ThreadAbortException that gets thrown when you call Response.End();. Check out this question.

Based on the fact that you have the Response.End(); call, I assume that the code you included is running in an event in an ASPX page. Correct?

If so, I suggest that you move the code where you load the file and serve it back to the client from the ASPX page into a Generic handler. The generic handler has the ASHX file extension. It is very simple - It has just one method and one property that you need to implement. The main thing is the ProcessRequest method. Sample from a handler called ServeFile.ashx:

public class ServeFile : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        byte[] fileBytes = File.ReadAllBytes("c:\\path\\to\\folder\\with\\files\\" + context.Request.QueryString["fileName"]);
        context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        context.Response.AddHeader("Content-Disposition", "attachment; filename=PSL.xlsx");
        context.Response.BinaryWrite(fileBytes);
    }

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

After building the handler, you can then change you aspx page to show a link to the handler with a suitable identifier in the QueryString that the handler uses to load and serve the correct file. In the sample the file is read from the file system but of course you can load it from db or get it some other way as well.

Community
  • 1
  • 1
user1429080
  • 9,086
  • 4
  • 31
  • 54