openning files in another browser page/tab - asp.net

i have an action that return a file content. i added:
Response.AddHeader("Content-Disposition", "attactment; filename:\"" + survey.File + "\"");
so that the image would be opened in another tab/page, gets opened in the current tab/page.
whats wrong with the header?

The content-disposition header instructs the user agent how it should present the data, and it is usually used when serving up binary data (as opposed to plain text). When set to "attachment", the display of the content is contingent upon further action of the user. In other words, the user should receive a prompt and must decide what to do with the content (usually given an "Open" or "Save" option).
You can not programmatically force a hyperlink to open up in a new tab. Even if you could, you should not. This behavior should be controlled by the user agent. As a user, when I want to open something in a new tab, I use the mouse-wheel-click because that is how my browser is configured.

You cannot control browser's tab behaviour by using HTTP headers - there is nothing in your code that affects this.
What might help you is changing HTML code that points to your download - if you are using tag you can set its target attribute to _tab or _blank and it will work in many browsers.

Related

Web form non-responsive after download

I'm working in ASP.NET (2.0) and we have a page where a user is able to select and download a series of files as a zip. I got this to work without undo difficulty by using the DotNetZip library (which is probably not relevant to the problem, but included for completeness.)
After the user checks which files they want to download, the page does a postback, and in the button click event handler, I use the following code:
Response.Clear();
Response.BufferOutput = false; // false = stream immediately
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "filename=FileRequest.zip");
using (ZipFile zip = new ZipFile())
{
zip.AddFile(MapPath("/datafiles/fileToZip.pdf"), "");
zip.Save(Response.OutputStream);
}
Response.Close();
And this all seems to work great. The user clicks the button, a download window pops up, the user downloads the zip. All is good...
...until they decide they want to do something else on the page. The buttons in the form are no longer responsive. For instance, if I click the download button again, it does nothing. If I reload the page, I can repeat this behavior...it works once, then does nothing.
I'm not understanding why the browser doesn't send the new request. It's not "spinning" or otherwise acting busy. I thought that this might be a browser issue, but I've repeated it in both IE and Firefox, so it seems likely that it's something I'm not understanding. Strangely, it's only form submission elements that seem to be non-responsive. Javascript still works, and so do regular links.
So why is this happening, and how do I get around it?
The problem is likely down to you returning;
Response.ContentType = "application/zip";
Once this has been sent (along with the actual content), the browser would assume it has nothing left to do (I believe).
You probably should create a new window specifically for downloading the files by saving the file selection in a session parameter (or equivalent) and opening a popup window that has your download code in.
This will leave the parent page in a suitable state.
Content-disposition header seems to be a discouraged solution. But the same effect of ASP.NET forms not being responsive occurs if you use standard Redirect to a zip file.
I solved very similar problem (returning *.csv files by the server for download) using Tančev Saša's code in "Response.Redirect to new window" Q&A and it works great. Perhaps it might produce some popup warnings in some browsers, but I think this is how it's often done in download sites.

Precompiled views: can I still read the contents at runtime?

I have my views setup to pre-compile, and therefore, at runtime if I were to try and read the view file (e.g. "~\Views\User\Report.cshtml") I'd get the following dummy-text, as opposed to the contents of my view:
This is a marker file generated by the precompilation tool, and should not be deleted!
Problem is, I'd like to re-use the cshtml view, and rerender it another way at runtime, but I cannot due to the above restriction.
The scenario:
An admin can see a list of users in a /User/Report route. It outputs some HTML that has a list of all users, and their information in an HTML table. These admins frequently want to download this html file (styles and all) to email it as an attachment to someone else. They could, of course, go to File->Save in their browser, but I wanted to simplify that action by adding a link to the page "Download this report as HTML" that would simply return the same page's content, as a forced-downloaded HTML file (2012-07-11_UserReport.html).
So, what I tried to do was re-render the view by running the Report.cshtml file's contents through ASP.NET's File() method, like this:
var html = System.IO.File.ReadAllText(Server.MapPath(#"~\Views\User\Report.cshtml"));
var bytes = System.Text.Encoding.UTF8.GetBytes(html);
return File(bytes,"text/html",string.Format("{0}_UserReport.html",DateTime.Now.ToString("yyyy-MM-dd")));
But, like I mentioned earlier, the file comes back as the dummy-text, not the view, since I'm pre-compiling the views.
I understand that to get around the pre-compilition, I could simply copy the Report.cshtml file, and rename it to Report.uncompiled (adding it to the csproj as of course) and read the contents of it, that's an ok solution, but not good enough.
What I would really like to know is: Is there a way I can get at that pre-compiled content? I looked in the Assembly's embedded resources, and they are not there. Any ideas/suggestions?
Updated with current solution
So after searching around some more, and trying to use WebClient/WebRequest to just make a request to the route's URL and send the response back down to the user to download while at the same time trying to pass the user's .ASPXAUTH cookie (that made WebClient/WebRequest time out for some reason? I even tried to create a new ticket, same result) I ended up going with what I didn't want to do: duplicate the view file, and rename it so it's not precompiled.
The view file (Report.uncompiled) had to be modified a bit as it was, and then I ran it through RazorEngine's Razor.Parse method and got what I needed, but it just felt hackey. Would still like a way to access the view file (Report.cshtml) even after it's compiled.
var templateHtml = Razor.Parse(System.IO.File.ReadAllText(Server.MapPath(#"~\Views\User\Report.uncompiled")),model);
var bytes = System.Text.Encoding.UTF8.GetBytes(templateHtml);
return File(bytes, "text/html", string.Format("{0}_UserReport.html", DateTime.Now.ToString("yyyy-MM-dd")));
Would the WebClient class work?
using System.Net;
using (WebClient client = new WebClient ())
{
client.DownloadFile("http://yourwebsite.com/test.html", #"C:\directory.html");
// If you just want access to the html, see below
string html = client.DownloadString("http://yourwebsite.com/test.html");
}
Just have this fire whenever your user clicks a button and then it will save the current content of the page wherever? You could probably also have a directory selector and feed whatever they select into that second parameter.
It essentially does the same thing as the browser save as, if that's what you want.

Pop up to save image in asp.net

I am using asp.net 3.5 and C#.
I have a image which I want user can download.
Like, there would be a download button or link. When user click on this link he will be prompted with a pop up to save that image to his desktop.
I have tried with
<a href ="path" > </a>
but it is opening the image in other page, I want user to be prompted to either save or view the image,
please help
Thanks in advance
You need to write an IHttpHandler that serves the image along with a Content-Disposition header.
For example:
Response.AppendHeader("Content-Disposition", "attachment; filename=\"MyImage.png\"");
Response.TransmitFile(path);
You would probably pass the image name on the query-string.
If so, make sure it doesn't contain / or \, or attackers will be able to read arbitrary files.
You need to have another page or, better yet, an HttpHandler, that takes the image path as part of the query string or as a post parameter that will send the response with Content-Disposition set to attachment. Setting the content disposition this way will cause the browser to display the file download dialog. A slightly easier way, though it depends on the user doing something extra is simply to have the link open the image in a new page and let the user right-click on it and do a "Save As".
Download
or
<a href="/path/to/image" target="_blank">
Load Image in New Window then Use Save As</a>

Close pop up window after binary file is sent to browser

Is there a way to close a pop up window after the page writes binary data (PDF) to the browswer?
Here are the details:
Whenever my web appilcation needs to print, it will pass some parameters over to a pop up window, which will display the print options. When the user clicks on the Print button, it will set the src of a iframe that will call the page that does the printing.
I have PDFConverter to convert URL / HTML to a pdf file. At the end of the converting, it will write the binary to the browser. Here are some code:
response.AddHeader("Content-Type", "binary/octet-stream");
response.AddHeader("Content-Disposition",
"inline; filename=" + fileName + ".pdf; size=" + pdfBytes.Length.ToString());
response.Flush();
response.BinaryWrite(pdfBytes);
response.Flush();
After this is done, i will need to close the pop up window. However it seems like you can't do anything after the response is flushed. Any ideas?
Thanks in advance!
Angela
Instead of creating the iframe in the popup window, you could create it in the parent window. This way once the user clicks the print button, you could safely close the popup without interupting the printing process. But instead of going through all the pain of creating new popups windows which might be blocked by some browsers, I would simply create some placeholder in the main page so that the user could choose printing options and then print the document.
Just in case anyone else is having the same problem. This is the solution that seems to work for me.
I use the jQuery Simple Modal to show my option list page. On this page, I have a window timer running every 1 second to check against the server if the print job is done. I use ajax for that. Once the job is done, I update the session variable, and the ajax call to the server will pick up the session value and close the pop up window.

Make PDF display inline instead of separate Acrobat Reader window

I've got an ASP.NET ashx class that retrieves data from a database, creates a PDF file using iTextSharp, and streams the PDF to the browser. The browser (IE and Firefox at least) is launching Acrobat Reader as a separate window to open the file. I'd like for it to display inline within the browser.
Is that something I can completely control from the server side? I'm already setting the Content-Type header to application/pdf, and I've tried setting Content-Disposition and Content-Length. Nothing so far has worked.
Is there another header I'm missing? Is there something in the PDF itself that tells the browser how to display it? Any other ideas?
Setting the content-disposition and content-type headers should do it, but you might also need to call Response.ClearHeaders() to clear other headers that have been set.
Also, try using Fiddler to see the actual headers and content from the response and compare them to those from a site that works like you want.
If you are using an ashx (web handler) try this:-
context.Response.AddHeader("content-disposition", "inline; filename=Something.pdf")
OK, turns out it was a stupid question, but I'm glad I asked it because I had never heard of Fiddler (which led me to the answer, which is why I'm accepting tspauld's answer). The PDF is generated by a web service that serves the file to a couple of different front-end sites. I was setting the content disposition to inline in the service, but that didn't matter, because the browser never got that header; it got the header from the front-end site (which was attachment). I changed it in the front-end site and that fixed it.
So the answer is that you have to have Content-Type=application/pdf and Content-Disposition=inline; filename=Something.pdf, as others have said.
Try generating them into your page using html OBJECT.
<OBJECT WIDTH=640 HEIGHT=480>
<PARAM NAME="SRC" VALUE="<%=filePath%>">
<EMBED SRC=<%=filename.pdf%> WIDTH=1000 HEIGHT=680>
<NOEMBED> PDF should have displayed here!</NOEMBED>
</EMBED>
</OBJECT>
If you need to stream the response with an ashx instead of being able to return an aspx, I think you may be out of luck.
Otherwise, I believe the settings to show in browser or not, is completely client driven and out of your hands.
So, I have a sample in one of my works that is what you need:
<cc1:ShowPdf ID="ShowPdf1" runat="server" BorderStyle="None" BorderWidth="0px"
Height="750px" Style="z-index: 103; "
Width="750px"/>
and in server side :
ShowPdf1.FilePath = String.Format("~/Handlers/Pdf.ashx?id={0}#view=FitH&page=1&pagemode=none&navpanes=1", myPublicationId);
I place here also some code from my PDF Handler :
Response.ContentType = "application/pdf";
byte[] bytes = YourBinaryContent;
using (BinaryWriter writer = new BinaryWriter(context.Response.OutputStream))
{
writer.Write(bytes, 0, bytes.Length);
}
Anyway If my post doesn't seem clear to you, have a look at this sample How to Display PDF documents with ASP.NET
I think this header will do what you want
Content-type: application/pdf
Since you say that is not working, then I suspect it is a configuration setting on the client side.
Check your installed version of Adobe Acrobat. There is a setting in preferences for "Internet" and a checkbox that says "Display PDF in Browser".
--
bmb
Here is an article on using the embed tag to do it:http://blogs.adobe.com/pdfdevjunkie/2007/08/using_the_html_embed_tag_to_di.html
If you have the budget, my company sells a set of products that includes an AJAX based image viewer that will let you view the PDF pages in line without Acrobat at all. In its simplest form, it is just a viewer, but you can layer in interactivity as you need.

Resources