Search code examples
c#asp.net-3.5

IE9 randomly popping Windows Security Dialog when I send down a binary blob as a .xlsx


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);
}

Solution

  • 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.