Write Binary Files to the Browser
-
I tried to write binary files to the browser based on the codes found in Microsoft Knowledge Base Article 306654: //Set the appropriate ContentType. Response.ContentType = "Application/pdf"; //Get the physical path to the file. string FilePath = MapPath("acrobat.pdf"); //Write the file directly to the HTTP content output stream. Response.WriteFile(FilePath); Response.End(); The codes works for many kinds of file types, like DOC, PPT, XLS... but not for PDF. When it's a PDF file, Response.End will throw a ThreadAbortException because "the current response ends prematurely". I also tried BinaryWrite, Flush, no difference. Anyone has any suggestion? Thanks.
In looking at that, and also what I know about the ThreadAbortException, I would say that it seems, from the code, that it works correctly. Whenever you do a Response.End() or a Response.Redirect(), a ThreadAbortException is thrown. This is normal behavior. But, you might try this method: From MSDN
String FileName; FileStream MyFileStream; IntPtr FileHandle; long StartPos = 0, FileSize; FileName = "c:\\temp\\Login.txt"; MyFileStream = new FileStream(FileName, FileMode.Open); FileHandle = MyFileStream.Handle; FileSize = MyFileStream.Length; ... Response.WriteFile(FileHandle, StartPos, FileSize); MyFileStream.Close();
It might work a bit better, either that, or, provide a link for the user to click on to download the pdf themselves. At a minimum, I would wrap a try catch around the code and see what is going on aside from the ThreadAbortException. Soemthing like this:try { ... downloading code here } catch(ThreadAbortException tex) { ... do nothing here, we don't care about the exception, we just don't want to throw it. } catch(Exception ex) { ... see what other exceptions might be creeping up... }
Also, on another thought, it could possibly be Acrobat that is causing the problem. With the WriteFile, the file itself is written into the response stream. Now, I know on my machine, when I download a pdf and view it in the browser, the Acrobat OCX always wants to check for a newer version and will hang my browser at times. MAybe something like this is happening? HTH, Bill P. Oakland, CA
-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCM/MU/B dpu s--:-- a32 C++++$ ULH+++ P+++ L++ E+ W+++$ N++ o K? w++++$ O-- M V-- PS+ PE+ Y++ PGP++ t++@ 5++@ X++ R+@ tv b++ DI++ D+++>++++ G++ e++ h---- r+++ y++++ -----END GEEK CODE BLOCK-----
-
In looking at that, and also what I know about the ThreadAbortException, I would say that it seems, from the code, that it works correctly. Whenever you do a Response.End() or a Response.Redirect(), a ThreadAbortException is thrown. This is normal behavior. But, you might try this method: From MSDN
String FileName; FileStream MyFileStream; IntPtr FileHandle; long StartPos = 0, FileSize; FileName = "c:\\temp\\Login.txt"; MyFileStream = new FileStream(FileName, FileMode.Open); FileHandle = MyFileStream.Handle; FileSize = MyFileStream.Length; ... Response.WriteFile(FileHandle, StartPos, FileSize); MyFileStream.Close();
It might work a bit better, either that, or, provide a link for the user to click on to download the pdf themselves. At a minimum, I would wrap a try catch around the code and see what is going on aside from the ThreadAbortException. Soemthing like this:try { ... downloading code here } catch(ThreadAbortException tex) { ... do nothing here, we don't care about the exception, we just don't want to throw it. } catch(Exception ex) { ... see what other exceptions might be creeping up... }
Also, on another thought, it could possibly be Acrobat that is causing the problem. With the WriteFile, the file itself is written into the response stream. Now, I know on my machine, when I download a pdf and view it in the browser, the Acrobat OCX always wants to check for a newer version and will hang my browser at times. MAybe something like this is happening? HTH, Bill P. Oakland, CA
-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCM/MU/B dpu s--:-- a32 C++++$ ULH+++ P+++ L++ E+ W+++$ N++ o K? w++++$ O-- M V-- PS+ PE+ Y++ PGP++ t++@ 5++@ X++ R+@ tv b++ DI++ D+++>++++ G++ e++ h---- r+++ y++++ -----END GEEK CODE BLOCK-----
Thanks for your reply. I tried your codes and it turned out to be same. If I don't use Response.End, no exception and works for most file types, but not PDF. The PDF file shows nothing in explorer. If use Response.End, PDF file will make Response.End throw an exception. Some guys suggests just igore the exception, I did it but PDF files won't show up. If I put the file address directly into IE address bar, it works. But I want more control of downloading of the files and prefer binary streem.
-
Thanks for your reply. I tried your codes and it turned out to be same. If I don't use Response.End, no exception and works for most file types, but not PDF. The PDF file shows nothing in explorer. If use Response.End, PDF file will make Response.End throw an exception. Some guys suggests just igore the exception, I did it but PDF files won't show up. If I put the file address directly into IE address bar, it works. But I want more control of downloading of the files and prefer binary streem.
Hmmm, not sure what would be going on. Have you checked other things like file permissions and such? HTH, Bill P. Oakland, CA
-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCM/MU/B dpu s--:-- a32 C++++$ ULH+++ P+++ L++ E+ W+++$ N++ o K? w++++$ O-- M V-- PS+ PE+ Y++ PGP++ t++@ 5++@ X++ R+@ tv b++ DI++ D+++>++++ G++ e++ h---- r+++ y++++ -----END GEEK CODE BLOCK-----
-
Hmmm, not sure what would be going on. Have you checked other things like file permissions and such? HTH, Bill P. Oakland, CA
-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCM/MU/B dpu s--:-- a32 C++++$ ULH+++ P+++ L++ E+ W+++$ N++ o K? w++++$ O-- M V-- PS+ PE+ Y++ PGP++ t++@ 5++@ X++ R+@ tv b++ DI++ D+++>++++ G++ e++ h---- r+++ y++++ -----END GEEK CODE BLOCK-----
-
Yes. I did changed the file permissions. In fact I put all kinds of files (DOC, PPT, PDF...) into one folder and set the security settings for the whole folder.
Ok, one last thing that I can think of... have you tried it from other client machines and/or another web server? Also, what version of the Framework are you using? I tried to recreate the problem here, and I cannot. I do get the exception, but my pdfs transfer just fine. HTH, Bill P. Oakland, CA
-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCM/MU/B dpu s--:-- a32 C++++$ ULH+++ P+++ L++ E+ W+++$ N++ o K? w++++$ O-- M V-- PS+ PE+ Y++ PGP++ t++@ 5++@ X++ R+@ tv b++ DI++ D+++>++++ G++ e++ h---- r+++ y++++ -----END GEEK CODE BLOCK-----
-
Ok, one last thing that I can think of... have you tried it from other client machines and/or another web server? Also, what version of the Framework are you using? I tried to recreate the problem here, and I cannot. I do get the exception, but my pdfs transfer just fine. HTH, Bill P. Oakland, CA
-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCM/MU/B dpu s--:-- a32 C++++$ ULH+++ P+++ L++ E+ W+++$ N++ o K? w++++$ O-- M V-- PS+ PE+ Y++ PGP++ t++@ 5++@ X++ R+@ tv b++ DI++ D+++>++++ G++ e++ h---- r+++ y++++ -----END GEEK CODE BLOCK-----
Yes, I also heard that though there's an exception, the PDF should shows up without problem. But on my machine it just won't show anything. My OS is Win XP Pro, VS.NET 2003 with framwork ver 1.1 (this may cause the problem). I tried different client - same story. I'll try another server.
-
I tried to write binary files to the browser based on the codes found in Microsoft Knowledge Base Article 306654: //Set the appropriate ContentType. Response.ContentType = "Application/pdf"; //Get the physical path to the file. string FilePath = MapPath("acrobat.pdf"); //Write the file directly to the HTTP content output stream. Response.WriteFile(FilePath); Response.End(); The codes works for many kinds of file types, like DOC, PPT, XLS... but not for PDF. When it's a PDF file, Response.End will throw a ThreadAbortException because "the current response ends prematurely". I also tried BinaryWrite, Flush, no difference. Anyone has any suggestion? Thanks.
At last I found out every time I click that download hyper link, the PDF file did be downloaded and opened in Acrobat Reader, but it’s shown neither in IE or independent Acrobat Reader window. Only when I accidentally opened a PDF file I found Acrobat Reader already opened so many copies of PDF files. I don’t know how to deal with this problem. I may have to ask user to right-click the link and choose Save Target As.
-
At last I found out every time I click that download hyper link, the PDF file did be downloaded and opened in Acrobat Reader, but it’s shown neither in IE or independent Acrobat Reader window. Only when I accidentally opened a PDF file I found Acrobat Reader already opened so many copies of PDF files. I don’t know how to deal with this problem. I may have to ask user to right-click the link and choose Save Target As.
-
I add this: Response.AppendHeader("Content-Disposition", string.Format("attachment; filename=\"{0}\";", strFile)); Now I can only show file in an independent window, not inside IE, but at least it can show PDF file.
You're right, not the greatest of solutions, but if it works, it works. :) I think that Adobe has really messed up with the newer acrobat versions. With the web update not auto-timing out and invisible windows, it's a wonder why GhostScript hasn't taken off.. ;) Well, anyhow, great job on the solution, sorry I couldn't be more help! HTH, Bill P. Oakland, CA
-----BEGIN GEEK CODE BLOCK----- Version: 3.21 GCM/MU/B dpu s--:-- a32 C++++$ ULH+++ P+++ L++ E+ W+++$ N++ o K? w++++$ O-- M V-- PS+ PE+ Y++ PGP++ t++@ 5++@ X++ R+@ tv b++ DI++ D+++>++++ G++ e++ h---- r+++ y++++ -----END GEEK CODE BLOCK-----
-
I tried to write binary files to the browser based on the codes found in Microsoft Knowledge Base Article 306654: //Set the appropriate ContentType. Response.ContentType = "Application/pdf"; //Get the physical path to the file. string FilePath = MapPath("acrobat.pdf"); //Write the file directly to the HTTP content output stream. Response.WriteFile(FilePath); Response.End(); The codes works for many kinds of file types, like DOC, PPT, XLS... but not for PDF. When it's a PDF file, Response.End will throw a ThreadAbortException because "the current response ends prematurely". I also tried BinaryWrite, Flush, no difference. Anyone has any suggestion? Thanks.
RT1970 wrote: I tried to write binary files to the browser based on the codes found in Microsoft Knowledge Base Article 306654: //Set the appropriate ContentType. Response.ContentType = "Application/pdf"; //Get the physical path to the file. string FilePath = MapPath("acrobat.pdf"); //Write the file directly to the HTTP content output stream. Response.WriteFile(FilePath); Response.End(); The codes works for many kinds of file types, like DOC, PPT, XLS... but not for PDF. When it's a PDF file, Response.End will throw a ThreadAbortException because "the current response ends prematurely". I also tried BinaryWrite, Flush, no difference. Anyone has any suggestion?
Have you tried setting the ContentLength? I had a similar problem with PDFs and setting this property to the actual file size cured the problem for me.
Andy Hochstetler
-
RT1970 wrote: I tried to write binary files to the browser based on the codes found in Microsoft Knowledge Base Article 306654: //Set the appropriate ContentType. Response.ContentType = "Application/pdf"; //Get the physical path to the file. string FilePath = MapPath("acrobat.pdf"); //Write the file directly to the HTTP content output stream. Response.WriteFile(FilePath); Response.End(); The codes works for many kinds of file types, like DOC, PPT, XLS... but not for PDF. When it's a PDF file, Response.End will throw a ThreadAbortException because "the current response ends prematurely". I also tried BinaryWrite, Flush, no difference. Anyone has any suggestion?
Have you tried setting the ContentLength? I had a similar problem with PDFs and setting this property to the actual file size cured the problem for me.
Andy Hochstetler
-
I tried this: FileInfo fileInfo = new FileInfo(strPath); Response.AppendHeader("Content-Length", fileInfo.Length.ToString()); Response.AppendHeader("Content-Disposition", string.Format("inline; filename=\"{0}\";", strFile)); and got the same exception.
Here's code from a production app that has been running for nearly a year that serves PDFs. We noticed some problems with IE 5.5 without the latest service packs. However, no server-side problems. Document CurrentDoc = Document.Find(currentArea, currentUser, DocumentID); string TempFilePath = ConfigurationSettings.AppSettings["TempDir"] + "/" + SessionID + "/" + CurrentDoc.FileName; if (Method == "View") { LogEntry.Save(currentUser, CurrentDoc, LogEntry.AccessTypeEnum.View, DateTime.Now); Response.AddHeader("Content-Disposition", "inline;filename=" + CurrentDoc.FileName); } else { LogEntry.Save(currentUser, CurrentDoc, LogEntry.AccessTypeEnum.Download, DateTime.Now); Response.AddHeader("Content-Disposition", "attachment;filename=" + CurrentDoc.FileName); } // Serve it CurrentDoc.SaveDocContentsToFile(TempFilePath); Response.AddHeader("Content-Length", CurrentDoc.FileSize.ToString()); Response.ContentType = CurrentDoc.ContentType; Response.WriteFile(TempFilePath); Response.End(); Andy Hochstetler
-
Here's code from a production app that has been running for nearly a year that serves PDFs. We noticed some problems with IE 5.5 without the latest service packs. However, no server-side problems. Document CurrentDoc = Document.Find(currentArea, currentUser, DocumentID); string TempFilePath = ConfigurationSettings.AppSettings["TempDir"] + "/" + SessionID + "/" + CurrentDoc.FileName; if (Method == "View") { LogEntry.Save(currentUser, CurrentDoc, LogEntry.AccessTypeEnum.View, DateTime.Now); Response.AddHeader("Content-Disposition", "inline;filename=" + CurrentDoc.FileName); } else { LogEntry.Save(currentUser, CurrentDoc, LogEntry.AccessTypeEnum.Download, DateTime.Now); Response.AddHeader("Content-Disposition", "attachment;filename=" + CurrentDoc.FileName); } // Serve it CurrentDoc.SaveDocContentsToFile(TempFilePath); Response.AddHeader("Content-Length", CurrentDoc.FileSize.ToString()); Response.ContentType = CurrentDoc.ContentType; Response.WriteFile(TempFilePath); Response.End(); Andy Hochstetler