user1790300
user1790300

Reputation: 1745

File Uploading as an atomic operation

I am currently developing an application using mvc 3 and c#. I need to implement a controller for file uploading. I have a db table that stores the file metadata, name, size, type, path to file, purpose, etc. I want to store the actual file as a blob on a windows azure server and use the db row as a pointer to it.

I would like to save the item connected to the file, i.e., Person Profile(purpose), for example, then perform the upload after I get the primary key for the profile so I can make the necessary association, then upload the file and save the file's metadata.

How can I make this atomic if a user can select the file before the button is pressed to save the profile page.

It seems like I would have to somehow write the file to a session variable or write the file to some temporary folder(staging) before completing the remaining steps. Is there a better way to perform these steps that would guarantee atomicity?

Upvotes: 3

Views: 1500

Answers (3)

OnoSendai
OnoSendai

Reputation: 3970

IMHO the problem lies in the fact that the architect thought of this process as an atomic operation, while the user experience would say otherwise. You're spot in the middle of the conflict. =)

You may guarantee atomicity for the two distinct processes, and data unity post-process. Let me make some wild guesses, and suppose you're implementing a profile creation process for the current (interactive) user.

  • Allow the user to upload its picture; commit it to your storage, mark it as transactional, add the SessionID metadata to it.

  • After the user finishes creating his/her profile, scan your storage for pictures with the same SessionID. Bind the two together (associate file ID with profile ID, for example.) A more sophisticated process would include, for example, a 'profile creation' cookie with an exclusive ID that should be stored instead - so if the user abandons that session and returns later the uploaded file can still be used.

  • Implement a 'garbage collector'. Dispose of unused files after a threshold is met (time or otherwise.)

I know these suggestions doesn't exactly cover your original request, but they may serve to streamline your implementation.

Upvotes: 7

clamchoda
clamchoda

Reputation: 4991

What Database are you using? You could begin to make this atomic by wrapping your insert for obtaining the Primary Key in a try / catch, using an SQLTransaction Class, making use of SqlTransaction.Rollback Method and SqlTransaction.Commit Method's to undo the insert if any exceptions are caught with the file transfer

try
{
 // conn.BeginTransaction();
 // Insert
 // File Transfer
 // Catch Exceptions
 // transaction.Commit();
}
catch (Exception ex)
{
  // Roll back Insert if file transfer fails
  // transaction.Rollback();
}

Upvotes: 2

Kevin Stricker
Kevin Stricker

Reputation: 17388

It's unclear from the question where you're having trouble.

If you have an html multipart/form-data form being posted to the controller, the file gets posted with the rest of the data as one request. When you're ready to do something with the file's data, you just access the InpustStream property of the HttpPostedFileBase that I assume you have automatically binding somewhere. No need to save a temporary file, IIS already did that for you.

If, on the other hand, you want to make sure the profile gets created before any data gets uploaded, then you'll need to handle that with separate HTTP requests (But that is the opposite of an atomic operation, so I'll assume that isn't what you need.)

If what you want is to handle the case where a file gets uploaded successfully but the server detects problems with some other part of the form, and you don't want the user to have to wait for the file to upload again, yes, you will want to save a reference to the file somewhere temporary so that it doesn't get lost between requests (like a session variable or write back to a hidden field on the form).

Upvotes: 0

Related Questions