I have a simple form which the users can use to upload images. It has a preview button so when User selects an image and clicks on preview, a postback occurs and I save the image to temporary folder and resize it and show it on the page. from there, the user can either submit form or edit the form. If he submits, everything is okay, I copy the resized image into correct folder.
If he clicks edit, and chooses another image, I need to delete the uploaded files (both original and resized) and If I do this:
File.Delete(HostingEnvironment.MapPath(TmpDirectory + PostImageName + ".jpg"));
File.Delete(HostingEnvironment.MapPath(TmpDirectory + PostImageName + "_small_.jpg"));
I get an exception saying some other process is using the image and It cant delete. (even after postback!)
and Also, if, instead of deleting that file, I try to save the new image with the same name so that it would overwrite, it still throws the error because file already exists.
There is no limit to the number of times the user can edit / preview so I cant save files incrementally (it doesn't even make sense to do this)
Also, after the postback, when the user goes back to edit mode and views the form the file upload control is empty. how can I get the file upload control to retain the value? all the other textboxes and text areas and checkboxes behave properly.
to summarize these are my questions:
1) how on earth (or rather, in c#) can I delete files without getting that exception?
OR
1) how to overwrite files?
2) how to make the file upload control retain its value between postbacks.
Thanks.
The exception talks for itself : Your file is still being used/opened by another process, i.e. thread, that you have launched. I bet it is the process by which you open the image file for reading. Make sure you have closed the relevant stream, ten bucks that it will solve your issue.
Why are you using a Bitmap to open the file on the server side? You should simply stream the "file" using
Response.TransmitFile(physicalFileNameAndPath).
Where TransmitFile expects (as a string) the physical file path and name.
The problem stems from the the way you send the file to the client. The file is still "locked" by the previous step. If you fix this, you'll be able to delete the file if needed.
I've not used the FileUpload control but it looks like you're using ViewState (which is what helps retain the values in the fields after postback. Either the FileUpload control does not support ViewState or you've not configured it to use ViewState.
you could assign the required property of the FileUpload control with the correct "value" so it shows what you've expect. This would mean that you'd have to capture the said value when the form is posted and simply re-assign the value back to the FileUpload control's property during the DataBind.
Make sure that your current
process doesn't have a write handle
open to the files in question
If there are no handles then try
turning off your virus scanner; an
overly aggressive virus scanner
could be taking a lock on those
files just after they have been created. This might be preventing you from deleting the files.
Related
I have a project in C# that needs to upload files in a page with a lot of others information.
Problems:
1 - File upload doesn't give any feedback for the user, so they can't know how long will takes (doesn't work with UploadProgress and UpdatePanel).
2 - Some validations I can't do with javascript (relationships for example), so if I get any error on the server side, FileUpload loses the file and the user needs to upload the whole file AGAIN.
3 - End user have a really poor link, so for 10mb will takes a long time (10mb is the maximum allowed).
Solutions (none of them works great):
1 - I can use a client side file upload with javascript (like uploadify) and get the percentage, but works as async method so I need to block the screen to don't allow the user to do another things. My worry is more about when I receive the file and save it, because I need to link this file with the other entity if not I will lose the bridge between the file and the entity. (Same happens with the AsyncFileUpload Control). This doesn't solve the problem number 2.
2 - Just do everything synchronous as FileUpload, when all the files arrive to the server, save the file and put all the informations that I need in HiddenFields, so if I get any error on the server side I can recover the file. The problem is that I can't give any feedback for the user while he uploads the file. This doesn't solve the problem number 1.
3 - Split all the files from the others entities (this will mess a lot the project) and upload file individually. The problem is that if I do that I need some mechanism to create the link between the file and the entity AND I can't allow to use the file more than once, so probably this will request a lot of resources to check it. This solves the problems listed but I think create another, complex for the user and a lot of new verifications for the system.
4 - Create 2 buttons, one button VALIDATE for validations on the server side (with no file uploads) and after this check, allow the user to click on the SAVE button. This doesn't solve the problem number 1.
Well, as you can see I'm thinking a lot about the problem but I can't find a really good solution. One that fits all my needs. Anyone have a idea?
PS: I have FileUploads inside repeaters as well, so the IDs are automatics.
Firstly let me tell you that I searched in the internet, but could not get any help.
I need to develop an application where I need to show currently how many files are downloading and every files name, progress along with we have the option to cancel the download whenever we want. For better understanding I have attached an image the overall UI design. But I have a doubt that how at runtime I will keep appending files in the download Window? Suppose I am downloading a file, now after sometime i will start another file to download. How will I add that Download in the same window. Any ideas and codes and help would be a great help.
The data I will be getting from a cache in our application. the file name and how much bytes downloaded and total size everything is stored in the cache, but run time keep adding/removing the download Window is an issue. Help please
I would use an ObservableCollection to store the download information (file name, progress, etc.), then create a container (e.g. ListView) with an DataTemplate and then bind the collection to the control.
When you want add another file to the downloades files list, you simply add it to the ObservableCollection and it will automatically show up on the UI.
I have a ASP.NET app that at one point generates a PDF file and loads the next page. I can easily do this with two separate buttons but it is made much tougher when I try to do this with one button.
When both are fired by the same button the PDF will download but the page will not load. I even had the thread sleep after the file was transmitted but it would wait but then stop afterwards.
I have attached the code that I have been trying to make work:
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=labels.pdf");
Response.TransmitFile(Server.MapPath("~/"+randomNumber.ToString()+".pdf"));
Server.Transfer("~/createshipment.aspx", true);
You can't have two different responses from the server but you're trying to do so.
First - you'd like the server to return a PDF.
Second - you'd like the server to return the createshipment.aspx page.
This is just against the communication protocol. Probably the best solution is already presented by another user, competent_tech - you could open a new window (javascript's window.open) and this new window would return the PDF and in the same time the main window could post to the server and be redirected to the createshipment.aspx.
So in a nutshell you want to navigate to the next page that says something like "thank you for downloading this file" and start the download.
What you should do is on your button click you need to generate PDF and save it somewhere (on disk or DB - whichever is easier in your app), store the name/location of the new file (or primary key from DB) in a session variable and redirect to the next page. No reason to do transfer here. Then on that next page you should add a hidden iframe that points to your saved file.
Alternatively your button click could be just a link to the next page, which includes a hidden iframe pointing to the page that generates PDF. This is a bit simple but wouldn't work so well if you need to pass parameters from original page to the page that generates PDF.
This is because server.transfer "...terminates execution of the current page and starts execution of a new page by using the specified URL path of the page".
Your best bet is to open a new window in the client that gets the PDF and then perform whatever postback is needed to move the user to the next page.
I know this is old, but I'm just seeing it (looking for similar info myself).
I'm going to guess that this is causing issues:
Response.TransmitFile(Server.MapPath("~/"+randomNumber.ToString()+".pdf"));
You would need to map the path to the actual file and not some randomly created filename - or am I missing some steps?
I would like to write a Web Application that would have two buttons and directly from the browser would allow me to open two simple text files (using a File Open dialog box or something similar) and would then proceed to read in contents of those files and store them inside of a two strings. The key point here is that the exact files used to read from I don't known at runtime so it would be up to the user to select the files.
The goal is to be able to later compare those two strings but that part I already know how to do. My questions is this - is it even possible to do this inside of a Web Application (i.e. to call a File Open dialog box to allow the user to select files to read from) or would security limitations or some other Web Application related constraints prevent it from being done?
If it is possible, I would appreciate some sample code describing how to open files and how to read in contents of the selected files into strings. Othwerwise, I would like to know if it's not possible and I should consider doing a desktop application or try an entirely different way.
Thank you!
It is possible, but you would wind up having to upload both of the text files to the server and read the files into strings server-side.
All you would need to do is add two separate FileUpload controls to the page along with a button to post the files to the server.
If you don't want the page to refresh, you could always do the comparison via AJAX using the AsyncFileUpload control from the ASP.NET AJAX Toolkit.
Update
Reading the contents of the file should be relatively easy (as long as they are plain text):
var reader = new StreamReader(fileUploadControl.PostedFile.InputStream);
var contents = reader.ReadToEnd();
One way is to use the ASP.NET AJAX AsyncFileUpload control.
http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/AsyncFileUpload/AsyncFileUpload.aspx
In order to access the files from the server-side code (C# code) you'll need the user to upload them. The standard way to do this (and, for security reasons, the only way upon which you should rely) is with a file input element. In ASP.NET, you can use the FileUpload control.
You would essentially give the user two of these controls with which they can upload the two files. Then you'd read their contents on the server, save them however you wish (as files, to a database, just in Session for temporary use, etc.) and perform your logic on that data. Then build your output (the comparison part, which you said you have already) to display on the page refresh.
Be mindful of concerns such as what to do if the user tries to upload non-text files, very large files, etc.
That is not possible alone with JS. You would have to build a file upload (and store session information) or use Silverlight and a Javascript-Bridge to your Web-Application.
Here's an example for a FileOpenDialog in Silverlight: http://www.silverlightexamples.net/post/Open-File-Dialog-in-Silverlight.aspx
Here's an exmaple for a file upload via C#/Webforms http://support.microsoft.com/kb/323246
I have an ASP.NET web application that uses jQuery on client side.
On one of the web forms I have a bunch of controls to fill, and an upload control.
User can run upload while filling other entries on the form.
When user saves the form, all data including file is stored into database .
The question is what to do with uploaded file while user fills the form?
I have two possible solutions, but don't know which of them is more optimal
Cache uploaded file, and later, while saving, retrieve it and store into database with all other data.
Save file in temporary folder, and then read it.
What is the best solution for this?
Thanks in advance.
I think the most appropriate solution will be storing uploaded file in cache.
Here is the code
var fileKey = Guid.NewGuid();
var fileStream = new Byte[Request.Files[0].ContentLength];
Request.Files[0].InputStream.Read(fileStream, 0, Request.Files[0].ContentLength);
Cache[fileKey.ToString()] = fileStream;
The fileKey GUID can be stored in ViewState, or sent as the response to client.
Later, when whole form will be saved, cached file can be retrieved and stored into database with other data.
The good thing about this method is that if user navigates from the page cached file will expire, thus avoiding resource flooding.
We can set expiration time using
Cache.Add(fileKey, fileStream, null, DateTime.UtcNow.AddMinutes(10), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
function.
How about:
3: Store it in the database but marked as in an incomplete state
This could be a separate table, or the same table with a status column.
I fail to see the difference between the 2 options: what do you mean by caching the file? Isn't it the same as saving to a temp folder?
AFAIK, most sites will not start uploading until the entire form is filled up (what if your user cancels, or browses away?). They then display an interim progress bar ("please wait while we're analyzing your data...").
As a general design rule, receiving partial data at any point in time may lead to inconstant data later. If you must do it in steps, change your form to a wizard.
Like other people mentioned - you can simply upload it. You can do it in many ways:
Upload the files in a temporary folder, and when they finally say save or complete - you can move the file from that temp folder to the other folder where you'd usually keep regular files.
One more thing that you can do, whenever the user clicks on upload button for temporary files, is that you can check you temp folder and clear other files which have stayed there for more than 1-2 days/weeks so that way you know for sure you are not wasting space.
Perhaps, you can also have a timer on
your website that regularly cleans up
this folder. I'd say this is more
efficient and you don't have to wait
for users to come in and click on
upload button to clean up your space.