I am receiving file uploads async from the filled out user form posts [using a tool which uses iframes]] What i am doing is upon the form page setting up a field with a hidden GUID which I pass to the iframe in the querystring. Then the iframe page handles the upload using a basic method whereby it takes the first 2 chars of the guid for a directory and the next 2 for a subdir, basically to prevent having thousands of files in 1 dir.
My problem is this. If a user uploads a picture and never submits the form the file should be deleted I am thinking of using the cache object as this is a single server environment. So upon a file post the fileupload page checks the cache object for a postid if it finds one it deletes the existing file [they uploaded a file then changed to a new one], it writes the new file to the disk. My problem is what if they upload the file and just never submit the form I need to delete the file. I am guessing I can use a delegate in the cache object to fix this? Something like if the form submits it invalidates the cache object so it never expires, and records it in the database as a good file, and if not after 20 mins the cache object deletes whatever filename is in its key. Here is the code I have thus far
protected void Page_Load(object sender, EventArgs e)
{
string PostID = Request.QueryString["a"];
HttpFileCollection hfc = Request.Files;
for (int i = 0; i < hfc.Count; i++)
{
HttpPostedFile hpf = hfc[i];
if (hpf.ContentLength > 0)
{
if (Cache[PostID] != null)
{
File.Delete(Server.MapPath("~/Uploads/") +
Cache[PostID].ToString().Substring(0,2) +
Cache[PostID].ToString().Substring(2,2) + "/" + Cache[PostID].ToString());
}
System.IO.FileInfo fe = new System.IO.FileInfo(PostID);
string extension = fe.Extension;
string Directory1 = PostID.Substring(0, 2);
string Directory2 = PostID.Substring(2, 2);
if (!Directory.Exists(Server.MapPath("~/Uploads/") +
Directory1))
{
Directory.CreateDirectory(Server.MapPath("~/Uploads/") +
Directory1);
}
if (!Directory.Exists(Server.MapPath("~/Uploads/") +
Directory1 + "/" + Directory2)) {
Directory.CreateDirectory(Server.MapPath("~/Uploads/") +
Directory1 + "/" + Directory2);
}
hpf.SaveAs(Server.MapPath("~/Uploads/") +
Directory1 + "/" + Directory2 + "/" +
PostID + "." + extension);
Cache.Insert("PostID",
PostID + extension,
null,
System.Web.Caching.Cache.No开发者_StackOverflow社区AbsoluteExpiration,
TimeSpan.FromMinutes(20));
}
}
Just a thought, but can't you upload the files to a staging folder first? Move the files to the final location when the form is submitted. Make an assumption that any files still in the staging folder after a certain amount of time have been abandoned & then delete them using a script that runs periodically.
Have you considered using Session_End()
in the Global.asax to clean up the files? I've never used this event. I could be wrong but it's my understanding this is fired after the session is terminated either by timeout or a log out.
Creating a folder structure based on the first 4 characters of a guid will not be unique. A collision will happen. Use the entire GUID as the folder name. You could store the GUID in the database and later retrieve the GUIDs and scan the download directory removing the found directories.
Windows temp directories is are available in .Net Path.GetTempFileName()
精彩评论