Search code examples
asp.netdownloadimpersonationcontent-dispositiontransmitfile

Response.TransmitFile() with UNC share (ASP.NET)


In the comments of this page:

http://msdn.microsoft.com/en-us/library/12s31dhy%28v=VS.90%29.aspx

..it says that TransmitFile() cannot be used with UNC shares. As far as I can tell, this is the case; I get this error in Event Log when I attempt it:

TransmitFile failed. File Name: \\myshare1\e$\file.zip, Impersonation Enabled: 0, Token Valid: 1, HRESULT: 0x8007052e

The suggested alternative is to use WriteFile(), however, this is problematic because it loads the file into memory. In my application, the files are >200MB, so this is not going to scale.

Is there a method in ASP.NET for streaming files to users that's:

  • scalable (doesn't read entire file into RAM or occupy ASP.NET threads)
  • works with UNC shares

Mapping a network drive as a virtual directory is not an option for us. I would like to avoid copying the file to the local web server as well.

Thanks


Solution

  • Have you tried setting up an IIS vroot using the remote UNC path as its home directory? If it works, this may be the easiest solution. You can still enforce authentication barriers on the files (e.g. via an HttpModule, or perhaps even via the out-of-box forms auth module) but you can rely on IIS to efficiently stream the content once your auth filters give the go-ahead.

    A caveat: the last time I configured IIS in a UNC scenario was a long time ago (1998!!!) and I ran into intermittent problems with files being locked on the remote machine, making updating files sometimes problematic. Dealing with recovery after a UNC server reboot was also interesting. I assume in the 11 years since then those problems have been ironed out, but you can never be sure!

    Another approach may be to install a web server on the UNC machine, and then install a reverse proxy server on your web server, like the new IIS7 Application Request Routing module.

    If you're willing to tie up a server thread, you can use the approach recommended in KB812406 which deals with issues around RAM consumption, timeouts, client disconnection, etc. Make sure to turn off Response Buffering!

    The ideal maximum-control solution would be a "streaming HttpHandler" where, instead of having to send the output all at once, you could return a stream to ASP.NET and let ASP.NET deal with the details about chunking results to the client, dealing with disconnects, etc. But I was unable to find a good way to do this. :-(