0

So on our website, we have multiple reports that can be downloaded as an Excel Spreadsheet, we accomplish this by reading in a blank template file from the harddrive, copying it into a MemoryStream, pushing the data into the template with DocumentFormat.OpenXml.Spreadsheet; Then we pass the MemoryStream to a function that sets the headers and copies the stream into the Response.

Works GREAT in FF & Chrome, but IE9 (and 8, so my QA tells me) randomly pop a Windows Security login dialog asking you to log into the remote server. I can either cancel the dialog, or hit ok (the credentials seem to be ignored), and get the Excel file as expected. Looking at the queries (using CharlesProxy) I cannot get the login dialog to pop until I disable CharlesProxy again, so I cannot see if there's any difference in the traffic between my dev machine and the server. It also doesn't happen when running debug from my local-host, just from the Dev/Test server.

Any help would be useful, the code in question follows. This is called out of a server-side function in the code behind, hence the RespondAsExcel clears the response and puts in the xlsx instead.

            using (MemoryStream excelStream = new MemoryStream())
    {
        using (FileStream template = new FileStream(Server.MapPath(@"Reports\AlignedTemplateRII.xlsx"), FileMode.Open, FileAccess.Read))
        {
            Master.CopyStream(template, excelStream);
        }

    //Logic here to push data into the Memory stream using DocumentFormat.OpenXml.Spreadsheet;


        Master.RespondAsExcel(excelStream, pgmName);
    }


        public void RespondAsExcel(MemoryStream excelStream, string fileName)
{
    var contenttype = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    Response.Clear();
    Response.ContentType = contenttype;
    fileName = Utils.ReplaceWhiteSpaceWithUnderScores(fileName);
    Response.AddHeader("content-disposition", "inline;filename=" + fileName);
    Response.Cache.SetCacheability(HttpCacheability.NoCache);

    Response.BinaryWrite(excelStream.ToArray());
    //If that doesn't work, can try this way:
    //excelStream.WriteTo(Response.OutputStream);

    Response.End();
}

        public void CopyStream(Stream source, Stream destination)
{
    byte[] buffer = new byte[32768];
    int bytesRead;
    do
    {
        bytesRead = source.Read(buffer, 0, buffer.Length);
        destination.Write(buffer, 0, bytesRead);
    } while (bytesRead != 0);
}
Drogo
  • 117
  • 1
  • 4

3 Answers3

0

A couple of ideas come to mind regarding that "extra authentication dialog" that can always be dismissed...won't promise this is your issue, but it sure smells like a first-cousin of it.

Office 2007 and later documents open HTTP-based repositories with the WebClient libraries, which do not honor any of IE's security zone filters when requests are made. If the file is requested by IE, and host URL contains dots (implying a FQDN), even if the site is anonymously authenticated (requiring no credentials), you'll get the "credential" dialog that can be cancelled or simply clicked three times and discarded. I was dealing with this problem just yesterday, and as best I can tell, there's no workaround if the file is delivered with IE. There's some quirk about how IE delivers the file that makes Office apps believe it has to authenticate the request before opening it, even though the file has already been delivered to the client!

The dialog issue may be overcome if the document is delivered from a host server in the same domain as the requesting server, eg some-server.a.domain.com to my-machine.a.domain.com.

The second idea is something strictly born of my own experience - that the openoffice vendor format types sometimes introduce their own set of oddness in document stream situations. We've just used a type of application/vnd.ms-excel and, while it seems it should map to the same applications, the problems don't seem to be as prevalent.

Perhaps that can give you some thoughts on going forward. Ultimately, right now, I don't think there's an ideal solution for the situation you're encountering. We're in the same boat, and had to tell our in-house clients that get the dialog to just hit "Cancel," and they get the document they want.

David W
  • 10,062
  • 34
  • 60
  • As I was investigating this issue and trying to see what in the traffic might be causing this, I discovered that it doesn't matter whether we use this method of sending the stream directly to the response, or actually save the file to the server hard drive and then redirect the response to that file, both methods exhibit this problem. It DOES seem to be a bug in the way IE tries to open the .xlsx if you click to open instead of save. – Drogo Apr 23 '12 at 17:49
0

In your RespondAsExcel() method, change your content-dispositon response header from inline to attachment. This will force the browser to open the file as read only. See KB899927.

Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
James Lawruk
  • 30,112
  • 19
  • 130
  • 137
0

I had something similar with VBScript when using "Response.ContentType="application/vnd.ms-excel". I simply added the following code and the Windows Security popup window no longer appeared:

Response.AddHeader "content-disposition","attachment; filename=your_file_name_here.xls"