I browsed through your other questions and I just want to make sure that we're clear on a couple of things. (If anything here is blindly obvious please forgive me, I don't intend to be insulting, I just want to make sure we're on the same page.)
First, client and server. Anything server-side runs under the context of a user account and is relative to the machine that it runs on. If you say "save this to the desktop" using server-side code, then this is the server's local process's desktop which almost never makes any sense. If you are impersonating the logged in user, however, this might work except that you are saving it to the logged in user's desktop on the server. If the client and the server are running on the same machine and you are impersonating the client then this might actually completely work. Maybe.
Second, Right-click, Save As. When you right-click a link you are invoking a browser's built-in proprietary menu system. That system is browser and/or OS-specific and is not defined in any specification out there. In the 90's you might have been able to use VBScript to "send keys" and have Internet Explorer "click" that link but those days are long gone. The closest modern equivalent to this would be to write a plugin which I imagine you don't want to do (and would be browser and/or OS-specific).
Third, MIME types. Generally speaking, every HTTP response includes a MIME type which specifies the server's intent for the bytes being sent. These include things like text/html
and application/pdf
. When server-side code (ASP.Net) doesn't get invoked, for instance static files like images and CSS or even pre-generated files like your PDF, the server (IIS) looks up the file extension in a list to determine what MIME type to send. On the client side the browser uses the MIME type to determine what action to take. If it is text/html
it (probably) renders the HTML. If it is application/pdf
then the browser looks at its list of MIME types to see if any application has that MIME type registered. Most modern browsers have a built-in PDF renderer so the browser just passes the bytes on to that to render. If the browser isn't aware of that MIME it might ask the OS if it knows about it and has a registered handler available and if so it passes that through. If that all fails (possibly because a user such as me has disabled that specific MIME type) then either the browser just puts those bytes into the "Downloads" folder, it tries to interpret those bytes as text or it prompts to save.
Going a little deeper into this last one, per the HTTP spec (19.5.1 paragraph 3), if you send a MIME type of application/octet-stream
in addition to a header of Content-Disposition: attachment; filename="fname.ext"
then
the implied suggestion is that the user agent
should not display the response, but directly enter a `save response
as...' dialog.
This is what you are ultimately trying to achieve, right?
In your case, clicking the PDF link bypasses ASP.Net and IIS just looks up the file and sends the application/pdf
MIME type along with it. One fix is to de-register the PDF file extension from the system. This probably isn't the most portable solution, however. Similarly you could also just change the file extension to be application/octet-stream
and you (might) get the Save As dialog.
What I would consider the best option for forcing the Save As dialog would be to create a handler of some sort server-side that forces the MIME type and Content Disposition headers into the stream and then passes the file's raw bytes. You could do this in a couple of ways, maybe with an IHttpHandler
(maybe even better here) or possibly with just a single ASPX page that inspects the Query String. You'll want to perform some extra security and definitely make sure you don't allow path-like characters and commands in file names.