Disable Save and save as while downloading a file ASP.NET - c#

I'm creating a web page with a download option
when the user clicks the the download option he gets three options
Open
Save
Save As
I just want the user to see
Open
I'm using ASP.NET 4
Thank You
p.s. i tried google but no good

You can't do this, this would be a security risk. I think the next best thing is to have the user register an application to a uri scheme, this is something that needs to be configured on the client pc trough the registry. ( for windows )
Off course, this means your application needs to support this as well. You can see how that works here:
http://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
The best thing is to have this register when the application installs trough the installer, otherwise you can provide an executable to modify the registry, or do it manually on every client, or have the user download an executable from the site, which ever is feasible.
If you are developing the client application, you could go the other way and have it poll the webserver, but that is off course a more evolved solution.

Depending on the file type you are serving, you may be able to add the following header to the response message:
content-disposition: inline
Code:
Response.AddHeader("content-disposition", "inline")
This will tell the browser to open the file immediately instead of displaying the dialogue box. But it will only work if the browser supports the file type.

Save, Save As, Open are your browser's options. Check in different browsers and you will see different options. Hell, I could make a browser with "Hit", "Hit Me", "Hit Me Again" and "Take a Look" options. You cannot control them from your asp.net code.
The best you can do from your code is to instruct your browser to display the downloaded content inline or as an attachment using:
Response.AddHeader("content-disposition", "attachment;filename=somefile.pdf")
or
Response.AddHeader("content-disposition", "inline")
The first option will trigger your browser's download options (in your case will show Save, Save As and Open buttons). In my case Chrome will automatically save the file without asking me anything.
The second option will directly open the file but ONLY if the browser will correctly identify the content-type of the downloaded content and if it CAN display it.
For example, for a PDF file you need to set:
Response.ContentType = "application/pdf";
and you need to have Acrobat Reader if you are using older browsers or you need to use a newer browser that already has a PDF plugin installed (IE7+, Chrome, etc...)
I hope this helps.

Related

Show inline pdf in default internet web browser from a winforms application

I have a winforms application in which i need to show a pdf (which is in a public remote url) in the default internet web browser of the user's computer once user clicks on an about option in a menu.
The remote url for the pdf is something like below:
https://path/to/the/pdf/file/myfile.pdf
I have googled a lot and see tons of examples using WebClient (synchronous and asynchronous) and also HttpClient seems it looks like WebClient is already obsolete.
So I have found below ones:
How to download a file from a URL in C#?
View PDF File using Windows Form C# from Remote URL
and also other examples, but in this case for asp.net, not for winforms:
https://stackoverflow.com/a/57568568
https://stackoverflow.com/a/40774857
I am interested in showing the remote pdf file directly in the user default internet web browser inline without needing to download the pdf file before. So is it possible? and if so, how?
In the last two link that I have provided about asp.net (not winforms), i see that it is possible by setting the inline property to true for the Content-Disposition header in the response, but of course, it is for asp.net, not for winforms, so I don't know how I can do the same in my case using winforms.
I want to avoid download the pdf file. In all the winforms examples I find (see links provided above) it always says to download the pdf file first in the local computer and then show it. I am not able to find how to show it inline without downloading it.
Note: I am using .NET 4.5

Save inside any folder instead in Desktop

Code:
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=pdfpage.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
The above code I used to allow a user of my web application to save a PDF generated on the server on his own device. The file is saving in as pdfpage.pdf on the desktop but I need to save this file in any folder. For example in E:\PDFs\pdfpage.pdf
Your question was wrong. I corrected part of it. Part of it is still wrong: you claim that the PDF is saved on the desktop. That may be true when you test it, but that is not true in general. For instance: if I would use your app, the PDF would be saved in the Downloads folder as defined in the settings of my browser.
There is no way you can define the download folder of a browser on the client by setting a parameter on the server.
There are some very simple reasons that explain that what you're asking for is impossible:
The server has no idea of the file structure on the client. For instance: there is no E: disk on my computer, so if you'd define the download folder as E:\PDFs\pdfpage.pdf, your web application wouldn't work.
It would be a serious security issue if a server were able to read the entire folder structure of the client machine in order to detect where to save a PDF file.
You are asking for something that is to be configured on the client side, in the browser of the end user. This can not be configured on the server side. For instance: I use Chrome, Firefox and Edge on my machine. I have defined different download folders for these different browsers. If I'd use your web app in one browser, it would download the PDF in a different folder depending on the browser I use.

How to enable editing in an office document that IE has opened from a login protected intranet?

The problem
I am working on an intranet, and have some problems with documents that IE lets the local Office installation open.
I am serving the users the files with the following anchor tag:
<a target="_blank" download="{{fileName}}" href="{{filePath}}">
When a user clicks this link, IE gives the user the decision to either open or save it. If the user chooses to open the file, and then decides that he/she wants to edit the file, they click "enable edit" in the top of the office application. This gives the user an error, as the Office application is unable to connect to the site and get the file the user want to edit.
Office Application Name cannot connect to (my file)...
What I want to do, is to let users edit a copy of the document they find online. A copy they then can save, and re-upload.
I think one of the problems is that the files are protected by a login. And maybe also that the intranet is running on SSL.
Research
Researching for solutions to the problem, I found this support page from Microsoft talking about something like what I am experiencing. In their error message three, they are writing:
Office Application Name cannot open the file.
In my case, I am getting the message:
Office Application Name cannot connect to (my file)...
It is almost the same, and Microsoft writes that one problem could be that:
When Internet Explorer communicates with a secure Web site through SSL, Internet Explorer enforces any no-cache request. If the header or headers are present, Internet Explorer does not cache the file. Consequently, Office cannot open the file.
This got me thinking, and I begun researching for the problem, finding StackOverflow pages like "How to configure static content cache per folder..." and "Leverage browser caching in IIS". I also checked The IIS.net Config Reference to see if there was anything here that could help me in my case.
I think the main problem is that when opening the file, it is not saved locally, and therefore the Office applications cannot edit it. As of now, I think the way to overcome this problem is to remove the no-cache header, and instead use some sort of short caching for the file so that it is forced to be downloaded by the browser.
What I have tried
Cache-Control
I tried the techniques from the two previous SO posts linked, trying to set up caching for static files in web.config, but forcing caching doesn't change anything (I used this technique to make sure the cache-control was right when I asked for a file). The office application still tries to open the file from a webpage that it doesn't have access to.
Content-Disposition
Another thing I tried was to force internet explorer to download the file. Completely removing the option to open it. Microsoft also has a support page about it. But it didn't seem to work.
In Global.asax I tried the following code (just to see if I could get word files to work):
<script runat="server">
void Application_PreSendRequestHeaders(Object sender, EventArgs e) {
Response.Headers.Set("Content-Type", "application/ms-word");
Response.Headers.Set("Content-Disposition", "attachment; filename=fname.ext");
}
</script>
But that only made Internet Explorer try to download all pages I tried to access.
Disabling authentication control on files
We always check to see if a user does in fact have access to the file requested. We don't want people to snoop around others files. Disabling this check resulted in all of the Office applications being able to open the file when a user wanted to edit a file. But this is a terrible solution, and just delivers a bunch of security problems.
The Question
So my question is, "how do I enable editing in an office document that IE has opened from a login protected intranet?" If it is something about the cache, then how do I get around this?
Is there some way that I can tell IE to save a local copy when a users chooses to "open" a file, and how can I tell the Office application to look for this locally cached version of the file instead of trying to download it from the server?
Update
I narrowed down the problem to being authentication of the office application. When I click the "enable edit" button in my Office application, the application is trying to download the file, so that it can edit the file. This request is then rejected by the server (serving a 404), as the Office application is not logged in, and does not have any kind of cookie to tell the server that is does in fact have access to that file.
This results in the user getting a message, informing the user that it was not possible to open the requested file.
You should be able to set the headers on individual calls so that files can be downloaded. If you are using MVC, the call return Controller.File(), there is a fileDownloadName option that takes care of setting the attachment; filename=... header so that it forces it to download.
Here's the Action (using MVC):
public FileResult Download() {
...
return File(filename, mimetype, fileDownloadName)
}
If you are not using MVC, use this call only when serving the file:
Response.Headers.Set("Content-Disposition", "attachment; filename=" + fileDownloadName);
BTW, This was a very thorough explanation of the problem!
When a user chooses to "open" instead of save, what IE does is save a copy of the file to the temp folder and then have the appropriate application open it. When closed, IE may or may not then delete the temp folder file.
When a user chooses to "enable editing" on a file from a non-local network, Offices closes the file, then reopens it in edit mode.
So your sequence of events is: IE saves file to temp. Office opens it. User clicks enable edit. Office closes it. IE deletes it. Office can't find it to reopen.
You could try NOT setting the content header, but IE may deduce the file type from the file extension anyway. Another option would be to educate the user. Include instructions telling them to save, and then open the saved copy. I generally approach the web from the assumption I have no control over what happens with the data I send my users. With the wide range of browsers and office applications out there, it's really a losing battle.

Local Machine Saving Report / How to path of local machine using ASP.NET C#

I have a problem, I have a web application (ASP.NET) it is installed in the server computer, if I run it on my computer (locally) of course it works properly, the reports are generated in my machine.
But when I installed it in the server and access the application from the server, and tried to generate report (using a button) it was not on my machine but it saves to the server machine.
I'm currently using this path as my file saving location:
This is where my Reports(.pdf) saves/generated
string folderDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
What should I do to save my report in my local machine if the web application is installed only in the server?
Btw. im using "iTextSharp" as my PDF Exporter/Generator and System.IO for file handling.
Thanks in advance have a nice day!
you have to download this PDF file.
1. use a link
2. or your server code will return you a file result directly.
It should be obvious that you shouldn't save the document as a file on the server, because the more users create a PDF, the more disk space you'll need (or you'll need to clean up the files after they have been server).
It is much better to create the PDF in a memory stream and then serve that stream to the browser.
See How to return PDF to browser in MVC? for an example.
If you want the user to see a "Save as" dialog box, you need to define an extra HTTP header:
Response.AppendHeader("content-disposition", "attachment; filename=yourfile.pdf");
Note the value attachment. By default, this value is inline in which case the PDF is shown in the browser. By changing this to attachment, the browser will open a "Save as" dialog box.

c# using SHDocVw.InternetExplorer. How can I find the URL of the last link clicked? Or the most recent get request URL?

I am accessing the SHDocVw.InternetExplorer from the SHDocVw.ShellWindowsClass(). I can see the page that the browser instance is currently on (the LocationURL property), but what I really need is the last get request that was done for the browser. My specific need is that my application was just launched to handle a file that was downloaded to the user's system via a link on the current web page. I need to know the URL of that file. LocationURL gives me the URL of the page that the link is on, but I need the URL of the file/link.
EDIT: The web application I've been trying to interface with is SharePoint. I wasn't able to find a way to extract the URL of the last clicked link (file downloaded) from Internet Explorer, so now I'm hoping to find a way to get that information from either SharePoint itself, or piggyback on the Name ActiveX control that SharePoint uses to manage the download of MS Office documents. Any SharePoint/Name ActiveX experts out there?
Since you can't get the url from Internet Explorer's history using IUrlHistoryStg::EnumUrls http://msdn.microsoft.com/en-us/library/aa767720%28VS.85%29.aspx
try making sure the file association is setup one the box and that your app can take a file path from the command line to start up.
I added these keys to my registry
[HKEY_CLASSES_ROOT\.sdr]
#="sdrfile"
[HKEY_CLASSES_ROOT\sdrfile\shell\open\command]
#="\"D:\\Shenanigans\\MyGreatApp.exe\" \"%1\""
on a Win7 box and IE/Sharepoint figured it out. If you poke around HKCR you'll see that it can get more complicated to setup file associations, but see if this works.
Sink DWebbrowserEvents2::OnBeforeNavigate2.

Categories