Recently I have been involved in developing a program to manage our own company’s contracts. Since every time I write a program I try go trough it with a new approach, I learned a lot of things and I am gonna share them with you here, tough they might not be that complicated.
One feature that I had to include in this contract tracking system was to create a Microsoft Word file out of each contract information and download (transmit) it automatically to client’s computer. In order to create such a Microsoft Word document on the fly I used “EK RTF” report generator ( http://ekrtf.code.net.ru ) but after creating the report I started thinking of possible ways by which I could save the file into clients. From my point of view the best approach is to start downloading the file automatically right after the report file is generated. It is not a good idea to show a link to target file and ask the end-user to click on that link because by the 1st click he has said that he wants the file!
By the way, firstly I decided to load the file into a byte array and write it into Response. Something like this:
byte buffer = File.ReadAllBytes(“myFile.doc”);
Response.OutputStream.Write(buffer, 0, buffer.Length);
After a little bit searching I came across to Response.TransmitFile method which has been introduced with .NET 2.0 and writes the specified file directly to an HTTP response output stream. The good thing about HttpResponse.TransmitFile is that it does not buffer the file in memory so that it can be used for large files.
At very first look this method seems simple but I had to change my code for several times to make it work properly! Actually I checked out some posts about this method in different forums and noticed that each person has used it in a way that did not worked for me.
Finally a code like this worked out properly:
FileInfo OutFile = new FileInfo(“TheFile.doc”);
Response.AddHeader(“content-disposition”, “attachment;filename=” + FileName);
Response.ContentType = “application/ms-word”;
Response.TransmitFile(“TheFile.doc”, 0, OutFile.Length);
The OutFile (of type FileInfo) is needed to get the file size. Afterwards, we have to call Response.Clean() to clean up previous Http Header information. The AddHeader methods indicates that we are sending an attachment, not a page, into the Response so that target browser will not open it. َ
All the magic is laid in Response.TransmitFile(“TheFile.doc”, 0, OutFile.Length); line. Response.TransmitFile opens the file (1st argument) , read it from a certain offset (2nd argument) up to a specified number of bytes (3rd argument) and send the bytes into Response output stream. All the operations related to opening and reading the file or streaming it towards the Response output are done automatically.
At the end, Respons.Fluch is called to flush Response content to the browser.
PS: Sometimes you cannot use the Response.TransmitFile method to transfer a file from a Windows Server 2003 SP 1-based computer to a client computer. This happens because when you use the Response.TransmitFile method to transfer a file to a client computer, the Response.TransmitFile method creates a file handle and sends it to the Microsoft Internet Information Services (IIS) Web site. If Microsoft ASP.NET closes the file handle too soon after the Response.TransmitFile method sends the file handle to the IIS Web site, the file transfer either does not start or does not succeed. To overcome this problem be sure you have installed latest Windows 2003 HotFixes and patches on your server.
– ASP GUY