Generated image display vs. download - asp.net

I have an MVC action that pulls an image from a database and sends it in the response via the File(byte[], string) method. When I navigate to the action in my browser, it downloads the file rather than display it in the browser.
I'm setting the file and setting the content type to "image/jpeg". Is there another header that needs to be set in order to get it to do what I want it to do?

Ok, mystery solved.
Controller.File() has an overload that takes no filename; just data and content-type. Using that overload causes the content-disposition to be set correctly. In retrospect, I guess that makes a lot of sense.

Response.ContentType
Response.ContentType = "image/jpeg";

I would use Fiddler to compare your response headers with a normal static JPG's response headers. That will tell you for sure.

Related

Let the user download a generated file in ASP.Net

I'm creating an ASP.Net web application and I want to add an export feature. That feature will generate a string (xml, to be specific) when a button is clicked.
I want to enable the user to download this string as a file.
Do I need to create a file on the server's hard drive and open a link to that file or is there a way to download the string directly (so ASP.net takes care of creating and removing the file)?
I am currently tryig to do the following:
Response.Clear();
Response.Buffer = true;
Response.ContentEncoding = Encoding.GetEncoding(1252);
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "attachment; filename=filename.txls");
//Multiple Response.Write(string) calls to add content to the file
Response.End();
Using firebug, I found out the the user receives the headers, but the file doesn't open.
The Internet Explorer is even able to show me the response text and has a button to save the file (both options are only avilable in the developer tools) and the file is correct, but nontheless, the file still doesn't open a window (nor a in-browser-preview).
When I use the Internet Explorer (which seems to have better Visual Studio debugging integration), a JavaScript error appears:
The EnableScriptGlobalization property cannot be changed during async postbacks or after the Init event.
Calls to Response.Write() seem to be a common cause of this issue. Of course, I call exactly that method multiple times.
I figured out that the JavaScript on the webpage (the script seems to be auto-generated) tries to parse the response, but of course it isn't formatted in the asp.NET internal communication format, but in my own XML format.
How can I tell the page to treat my page as a downloadable file?
string someXML=GetXMLContent();//I assume you have an implementation of this
Response.Clear();
Response.ContentType = "text/xml";
Response.AddHeader("Content-Disposition", "attachment; filename=filename.xml");
Response.Write(someXML);
Response.End();
Couple of things to note. It's probably better to build up your XML string early on, then write it to the response in one shot. It makes for cleaner code, because you can separate your concerns this way.
Also, I switched the content type to "text/xml", because this is not an Excel file. Also, your file extension was incorrect. XML by convention ends in .xml. I removed the content encoding because it's not necessary most of the time. If you're dealing with weird characters feel free to add it back. Also removed the buffer in the name of removing unnecessary things.
Try this, then try opening the resulting file in your text editor and verifying the content.
The problem was that the button responsible for triggering the Excel export was not a PostBackTrigger. As soon as I had changed it, everything worked like a charm.
Nontheless, I don't know hy this fixed everything. What does it change when I set the button as a PostBackTrigger

Handle cached images? How to get the browser to show the new version?

Hi,
When a webpage with a image(img_01.jpg) is loaded the image will be cached by the browser. Say that we update img_01.jpg and saves it with the same name, when visiting the same page the old image will be shown from the cache.
How should I handle this in ASP.NET MVC?
I know that in regular ASP.NET(no MVC) a extra component had to be created and this component would add a random number at the end of the filename. How do I do this in ASP.NET MVC?
BestRegards
You can use HTTP handlers for images to add expiration headers. But it mostly depends on a browser if expiration headers are used correctly. Does it help?
I decided to use the main object version number in the image filename, this will make sure that the end user always sees the correct image.
In C# when u r binding Image control just make the url as query string.
Ex:-
string _urlPhoto = "UploadPhoto" + "/" + Imagename + "?" + Guid.NewGuid().ToString();
Browser will always see it as new request and it will not take image from CACHE.

Unblock (jQuery BlockUI) after file sent to browser through response stream

I have an <asp:button /> that generates a PDF report. I want to use jQuery BlockUI to display a message that says: Generating Report..
Using: Response.BinaryWrite I am then sending the file to the user so it appears as a file download in the browser.
I cannot get $.unblockUI(); to fire. As soon as the file download begins or has completed or is cancelled I want it to dissappear. Currently it never does.. It's as though the page hasn't been re-loaded, I've hit the server but it comes back with the same page.
Things I have tried:
Setting a variable in JS to true so on document.ready() it will call a function if set to true. This doesn't work because even though I change the variable in code it doesn't change the HTML that is sent to the client.
This sort of thing: Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function() { $.unblockUI; }); //register with Microsoft way
$(document).ajaxStop($.unblockUI); //double the insurance and register with jquery way
never gets called..
Can this be achieved with an updatepanel?
Any thoughts?
Also in case it helps:
Response.AddHeader("Content-Disposition", "attachment;filename=""" & ShortFilename & """")
Response.AddHeader("Content-Length", byteArray.Length)
Response.BinaryWrite(byteArray)
Response.Flush()
Response.End()
I can see why this doesn't work sort of, the page is not refreshing in anyway there's just a response stream being sent to the browser, but surely there's an event I can latch on to?
An idea could be to create a child window that does the PDF loading and let the parent figure out when the child window has closed or something.
Is it possible for parent window to notice if child window has been closed?
The solution is to first block the UI as normal. Then make an AJAX request to your report generator, when the PDF is generated store it locally for a short time, or have it in a temporary folder that is cleared out when the user logs out or their login times out. Have the report generator return a success message and a URL.
Have the client ajax request handle the success message, remove BlockUI, then call the URL using:
window.location="http://yourURL/temp/report.pdf
The browser will start to download the file and you are done!
https://stackoverflow.com/a/7660817/181197

ASP.NET Response Content

I have tested this in IIS 6.1, IE 7, ASP.NET 3.5 SP1.
I have a file download in a method in my aspx codebehind:
Response.ContentType = contentType;
Response.AppendHeader("Content-Disposition", contentDisposition);
Response.BinaryWrite(file);
This works great, but if I attempt to modify any of my sever side controls the changes do not take affect. I have isolated this down to the call to ContentType, this apparently whipes all pending changes to the Response stream when called? Does this sound familiar to anyone?
If the code takes an alternate branch and the call to download does not fire the markup is modified as expected.
Any suggestions on how I can fix this and have the page flush the attachment and update the UI in the same response stream?
This is specifically for updating the ValidationSummary, so I could tear into the JS on the PageRequestManager event complete as a last resort, but I'd prefer not to rely on JS for this.
Not sure what you're trying to do - are you trying to simultaneously serve a download file and an update to the HTML page they linked to it from? That's not how HTML works.
If you want to achieve this result then you'll basically have to render a meta redirect that goes to the file which is returned in the HTML, that way the page will load and then the download starts (Like you'll see on a lot of download sites).
As fyjham said, I don't really understand what you're trying to do. A few tips that might help:
Keep in mind that the Render phase, when the content from your markup and controls is generated, happens as almost the very last phase in your code behind (well after Page_Load)
Once you flush headers, you can't set them again
Controls can override some HTTP headers
You can't mix a file download and HTML markup in the same HTTP response

ASP.Net HyperLink and Download directly?

want to have a Hyperlink-Button in a gridView in which I can display a Link for a direct download of files.
So far I am okay, but when I link the file in the NavigateURL, I don't get the file via click, I must right click -> Save as!
That I don't want. Any help?
You could set up an ashx file handler. Your ashx takes the request through the querystring, loads the proper file into memory, sets the proper response headers and streams the file to the browser:
FileInfo fileInfo = new FileInfo(PATH-TO-YOUR-FILE); //You need to specify this
context.Response.ContentType = YOUR-CONTENT-TYPE; //And this
context.Response.AddHeader("Content-Length", fileInfo.Length.ToString());
context.Response.WriteFile(fileInfo.FullName);
context.Response.Flush();
context.ApplicationInstance.CompleteRequest()
This lets you have some fine-grain control over the content that is being delivered if you have any concerns about security or maybe keeping track of who has downloaded what file, etc.
This sounds like a browser issue. Possibly the browser is trying to open up some application to handle this and failing. Double-check your application associations and/or try a new browser.
I would add also "Content-Disposition" header to response:
context.Response.AppendHeader("Content-Disposition", "attachment; filename = " + filename);

Resources