Saving a generated html document to specific folder in ASP.NET - asp.net

So I have written a simple program that creates an html document based on user input into a number of fields. Currently, when the user pressed a button it generates the document and automatically downloads onto the user's machine using the following:
Response.ContentType = "text/plain";
Response.Write(HTML.ToString());
Response.Flush();
Response.End();
But, I would like to have the file written to a folder on the user's machine when a user presses a button. So, let's say I want them to press the button and it automatically writes the file to their desktop. What would this code look like? (c#)
Thank you,
p.s. I have been trying something like this with no luck:
string filename = Server.MapPath("~/C:/Users/Sean/Desktop/new.html");
System.IO.StreamWriter textWriter = default(System.IO.StreamWriter);
textWriter = System.IO.File.AppendText(filename);
textWriter.Write(HTML);
textWriter.Close();

Using ASP.Net, you CANNOT force user to save any file on any specific location. Moreover the file you want user to save is HTML which will be rendered directly on browser i.e. user will not be prompted to save it on their machine.
So to answer your question, you cannot have ANY file automatically saved to user's machine. There has to be some manual intervention by the user(to select the path at which he/she wants to save it.)

Related

ItextSharp, Save Pdf Without Displaying Open / Save Dialog Box

Is it possible not to show Open/Save dialog? I would like to save the pdf file straight to specific disk location on client PC.
Yes, you can write the file directly to disk without the use of a save dialog. All you need is a directory path to write too.
string path = "C:\YourDirectoryPathHere";
System.IO.File.WriteAllBytes(Path.Combine(path, "NameYourFile.pdf"), myPDF);
This assumes myPDF is a byte[].

Allow only Logged in user to download images

I am working on an Application based on Monorails which generates images / charts at runtime. The code writes the images to OutputStreams and not to the Appserver hard drive. It allows the user to download the image. I want to make sure that only the logged in user is able to download the image and no one else.
For e.g if any user A tries to download image generated for user B user A should not be able to do that no matter what.
Note: I am not storing the file to the hard disk.
How can I implement this???
Below is the sample code I have written for the image download.
var stream = new MemoryStream();
Response.Clear();
Response.ContentType = "application/image";
Response.AddHeader("Content-Disposition","attachment; filename=" + imagefilename);
var array = stream.To Array();
Response. OutputStream.Write(array,0,array.length);
Response.End();
Please help me fix this issue.
Thanks,
Rahul
You need logic in the code to check if the user logged in 'owns' the image they are trying to download.
If they don't 'own' it, Response.End their request

storing the files in a web application in asp.net

I have set of components that i wish to let the users download from my web application.
Now the question is where should i place the files in app_data or create a separate folder in asp.net web application as shown here or is there any other optimal solution for this ?
What i mean by components is you can take a look at this ! So what is the best way to do store the components ?
Right now what i'm doing is: i'm storing the files in a external folder outside the application more specifically in documents folder of my c drive, and i'm storing the path to a component as a data element of the table, when ever user clicks on a particular row's button (in the grid view) i'm getting the title of that particular clicked row and querying the database table for the filepath of that component title using these lines of code:
String filePath = dr1[0].ToString(); //GETS THE FILEPATH FROM DATABASE
HttpContext.Current.Response.ContentType = "APPLICATION/OCTET-STREAM";
String disHeader = "Attachment; Filename=\"" + filePath + "\"";
HttpContext.Current.Response.AppendHeader("Content-Disposition", disHeader);
System.IO.FileInfo fileToDownload = new System.IO.FileInfo(filePath);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.WriteFile(fileToDownload.FullName);
Am i doing it properly ? Is there a better/optimal way to do it ?
A user simply needs read access to download a file, so you can simply create a directory claled "Downloads" and place them in there.
You can ensure that people can't "browse" that directory by disabling Directory Browsing and not placing any default docs in there (index.html, default.aspx for example)
What you are currently doing looks like a fairly standard way for providing downloads off your site.
I can't think of something more "optimal".

Getting full file path from code behind from file HTML input

I used file HTML input instead of FileUpload Web Control. Don't ask why but I just have to!
HTML:
<input type="file" id="image1" class="listUploadAdd" name="ImageAdd1" />
Code behind:
Dim ImageAdd1 As String = Request.Form("ImageAdd1").ToString()
I browsed from "C:/Orange.jpg" to upload and the result in Code Behind is just the image name "Orange.jpg" and not the full "C:/Orange.jpg" which is needed to get the file from local drive to be uploaded.
What is the best way to capture the full image path from code behind to be uploaded onto the server?
Thank you.
Can you add a runat="server" to the input element? :) Then it's pretty easy to store the file on your server
Request.Files("File1").SaveAs("c:\somedir\yourfile.txt")
If you want the original filename and path, try this:
Dim filename As string = Request.Files("File1").FileName
To download the file without using a runat="server" attribute, you can do this:
Dim file = Request.Files("File1")
Dim buf(file.ContentLength) As Byte
file.InputStream.Read(buf, 0, file.ContentLength)
IO.File.WriteAllBytes("C:\somedir\yourfile.txt", buf)
But you have to set the enctype on the form element in the html page:
<form id="yourform" runat="server" enctype="multipart/form-data">
I browsed from "C:/Orange.jpg" to upload and the result in Code Behind is just the image name "Orange.jpg" and not the full "C:/Orange.jpg" which is needed to get the file from local drive to be uploaded.
You won't be able to pull the file off the client's machine. When you're developing your program, the client and the server are the same machine but when you deploy it, the server and client will be different machines. When the code behind executes (on the server), if you try to open C:\Orange.jpg you will be trying to open it off the server's hard disk. This file will probably not exist.
When you upload a file from a web page, it will be posted to the server as part of the POST message. You can get the file out of this from the Form collection. You don't need to convert the uploader to the ASP.NET control, or add the runat="server" attribute. So long as your post the form, which contains the input element it will be submitted to the server.
The file's contents will be stored as a byte array in the form. You can save this byte array as a file to the server's hard disk somewhere.
In summary:
You don't need to know the path to the file on the client's machine, since you can't access it anyway. Use the file data that is posted as part of the form submit instead to save a copy of the file on the server.

Working with big files in classic ASP

I was wondering what's the best practise for serving a generated big file in classic asp.
We have an application with "export to excel" function that produces 10MB files. The excels are created by just calling a .asp page that has the Response.ContentType set to excel and has an HTML table for the data.
This gives as problem that it takes 4 minutes before the user sees the "Save as..." dialog.
My current solution is to call an .asp page that creates the excel on the server with AJAX and lets the page return the URL of the generated document. Then I can use javascript to display the on the original page.
Is this easy to do with classic asp (creating files on server with some kind of stream) while keeping security in mind? (URL should make people be able to guess the location of other files)
How would I go about handling deleted the generated files overtime? They have to be deleted periodicly as the data changes in realtime.
Thanks.
edit: I realized now that creating the file on the server will probably also take 4 minutes...
I think you are selecting a complex route, when the solution is simple enough (Though I may be missing some requirements)
If you to generate an excel, just call an asp page that do the following:
Response.clear
Response.AddHeader "content-disposition", "attachment; filename=myexcel.xls"
Response.ContentType = "application/excel"
'//write the content of the file
Response.write "...."
Response.end
This will a start a download process in the browser without needing to generate a extra call, javascript or anything
See this question for more info on the format you will choose to generate the excel.
Edit
Since Thomas update the question and the real problem is that the file take 4 minutes to generate, the solution could be:
Offer the user the send the file by email (if this is a workable solution in you server or hosting).
Generate the file async, and let the user know when the file generation is done (with an ajax call, like SO does when other user have added an answer)
To generate the file on the server
'//You should change for a random name or something that makes sense
FileName = "C:\temp\myexcel.xls"
FileNumber = FreeFile
Open FileName For Append As #FileNumber
'//generate the content
TheRow = "...."
Print #FileNumber, TheRow
Close #FileNumber
To delete the temp files generated
I use Empty Temp Folders a freeware app that I run daily on the server to take care of temp files generated. (Again, it depends on you server or hosting)
About security
Generate the files using random numbers or GUIds for a light protection. If the data is sensitive, you will need to download the file from a ASP page, but I think that you will be in the same problem again...(waiting 4 minutes to download)
Read file using FSO.
Set headers for Excel file-type, name according to file read and for download (attachment)
Flush response after headers are set. The client should display "save as" dialogue.
Output FSO to response. Client will download file and see progress bar.
How do you plan to generate the Excel? I hope you don't plan to call Excel to do that, as it is unsupported, and generally won't work well.
You should check to see if there are COM components to generate Excel that you can call from Classic ASP. Alternatively, add one ASP.NET page for the purpose. I know for a fact that there are compoonents that can be called from ASP.NET pages to do this. Worse come to worst, there's an Excel exporter component from Infragistics that works with their UltraWebGrid control to export. The grid need not be visible in order to accomplish this, but styles in the grid translate to styles in the spreadsheet. They also allow you to manipulate the spreadsheet programmatically.

Resources