Following this question it was recommend that I should create a server side file that can return a file from the file system. How would I go about doing this in c# and .net. I imagine I pass the filename as a query string, this is read by the page and the file returned. Not really sure where to start on this from a codding point.
4 Answers
You can use the Response.WriteFile method to send the contents of the file, though this may fail with larger files.
Be careful not to allow any filename to be specified in your query string, as users could then use this to access any file on your server. Better to have a database of files that are allowed with a name for each one, and look up a name supplied in the query string against this database to get the filename.

- 364
- 1
- 5
-
1`Response.TransmitFile` might be more useful for larger files. http://msdn.microsoft.com/en-us/library/12s31dhy.aspx – LukeH Feb 09 '10 at 17:39
I would recommend reading the file in as a byte[] and sending it out with it's content-type and content-disposition set in the response and then just perform a response.binarywrite and a response.flush:
Byte[] bytes = null;
try
{
if(!FileExists(_filename)) return null;
Byte[fs.Length] bytes
// get file contents
using(System.IO.FileStream fs = System.IO.File.Open(_file, FileMode.Open, FileAccess.Read))
{
fs.Read(bytes, 0, fs.Length);
}
}
catch(Exception ex)
{
System.Text.ASCIIEncoding oEncoder = new System.Text.ASCIIEncoding();
Byte[] bytes = oEncoder.GetBytes(ex.Message);
}
Context.Response.Buffer = false;
Context.ClearContent();
Context.ClearHeaders();
Context.ContentType = "application/octet-stream"; // Change this type as necessary
Context.AddHeader("Content-Length", bytes.Length.ToString());
Context.AddHeader("content-disposition", String.Format("inline; filename={0}", filename));
Context.Response.BinaryResult(bytes);
Context.Response.Flush();
The response portions will need adjusting according to your own delivery platform (separate page, in iframe, etc). You may not want to ClearHeaders() for instance.

- 37,325
- 10
- 89
- 104
-
-
@Rupert: I did mine in a web service initially, but this could be done with an aspx page with .cs code behind. If you put the file reading portion into a web service, you could then feed the byte array to any web page capable of consuming the service and the response.write could be done there. – Joel Etherton Feb 09 '10 at 16:31
-
When ever I have used web services in the past they returned XML (even when the return type was String). This is why I rulled this approach out. – Rupert Feb 09 '10 at 16:40
-
@Rupert: Yes, it's returned as XML, but the content of the data is still the byte representation of the binary data. Using BinaryWrite in the response will convert the byte array directly to the binary file again. I use this in a document server right now and can attest that it works for us flawlessly. – Joel Etherton Feb 09 '10 at 16:57
-
You could also use `Response.TransmitFile` to avoid buffering the contents in a `byte[]` array. http://msdn.microsoft.com/en-us/library/12s31dhy.aspx – LukeH Feb 09 '10 at 17:41
-
@Luke: tru dat, but TransmitFile fails for large files. Byte[] can be shunted out to the browser in chunks without timeouts and flushed when finished. – Joel Etherton Feb 09 '10 at 17:43
This thread has my suggestion for serving files outside the web root. It uses a buffer to keep memory usage down.
You can use Response.TransmitFile which is useful for transmitting large files. After this you should use Response.Flush(). The Content type is here for zip file.
Response.ContentType = "application/zip";
Response.AppendHeader("Content-Disposition", "attachment; filename = D:\Splitted Parts.zip");
Response.TransmitFile(zipFileName);
Response.Flush();

- 131
- 2
- 8