2013-08-06 64 views
2

我目前正在開發一個使用mvc 3和c#的應用程序。我需要實現一個文件上傳控制器。我有一個存儲文件元數據,名稱,大小,類型,文件路徑,目的等的數據庫表。我想將實際文件存儲爲Windows Azure服務器上的blob,並使用db行作爲指向它的指針。作爲原子操作的文件上傳

我想保存連接到文件的項目,例如,個人檔案(目的),然後在獲取配置文件的主鍵後執行上傳,以便我可以進行必要的關聯,然後上傳該文件並保存該文件的元數據。

如何讓這個原子,如果用戶可以選擇文件之前,按下按鈕來保存配置文件頁面。

看來我不得不以某種方式將文件寫入會話變量或在完成其餘步驟之前將文件寫入某個臨時文件夾(暫存)。有沒有更好的方法來執行這些可以保證原子性的步驟?

+1

文件上傳部分是在保存人之前完成的? – Matthew

+0

也許我已經完成了簡單的操作,但是爲什麼你不能保存它並跟蹤該ID,然後在文件獲取時更新文件上的其他元數據?有一個進程在X時間之後清除沒有* required *元數據的進程,或者在窗口卸載事件之後進行異步清理? – wilso132

回答

0

從問題出在哪裏不清楚。

如果您將HTML multipart/form-data表單發佈到控制器,則該文件將與其餘數據一起發佈爲一個請求。當您準備好對文件數據執行操作時,只需訪問HttpPostedFileBaseInpustStream屬性,我假設您已自動綁定到某個位置。不需要保存臨時文件,IIS已經爲你做了。

另一方面,如果您想確保在上傳任何數據之前創建了配置文件,那麼您需要使用單獨的HTTP請求處理該配置文件(但這與原子操作相反,所以我會認爲這不是你所需要的。)

如果你想要的是處理成功上傳文件但服務器檢測到表單的其他部分出現問題的情況,不希望用戶必須等待文件再次上傳,是的,您需要臨時保存對文件的引用,以便在請求之間不會丟失文件(如會話變量或寫回到表單上的隱藏字段)。

+0

我遇到的問題是如何保證數據庫操作和文件上傳都成功或者兩者均失敗。所以,數據庫被回滾並且文件永遠不會被推送到服務器。這兩個保存都發生在服務層。 – user1790300

+1

1.打開數據庫事務 2.執行數據庫操作(使用PostedFileBase獲取元數據) 3.上傳文件 4.提交事務 5.如果在4次回退事務之前失敗。如果在4期間失敗,刪除文件。 –

+0

在這些情況之前,我做一個小插入獲取生成的ID並利用它對照片的引用,直到過程不完成id被標記爲「temporáry」。帖子的下一個用戶自動查找已過期(經過一段合理時間後)的臨時和刪除以及與未完成的過程相關的圖片 –

1

你在使用什麼數據庫?你可以開始,如果任何異常都與文件傳輸

try 
{ 
// conn.BeginTransaction(); 
// Insert 
// File Transfer 
// Catch Exceptions 
// transaction.Commit(); 
} 
catch (Exception ex) 
{ 
    // Roll back Insert if file transfer fails 
    // transaction.Rollback(); 
} 
抓住了,使這個原子通過包裝您的插入獲得在一個try/catch主鍵,使用 SQLTransaction Class,利用 SqlTransaction.Rollback MethodSqlTransaction.Commit Method's撤消插入
5

恕我直言,問題在於建築師認爲這個過程是原子操作,而用戶體驗會另有說明。你處於衝突中。 =)

您可以保證兩個不同進程和數據統一後處理的原子性。讓我進行一些瘋狂的猜測,並假設您正在爲當前(交互式)用戶實施配置文件創建過程。

  • 允許用戶上傳其圖片;將其提交到您的存儲,將其標記爲事務性,將SessionID元數據添加到它。

  • 用戶完成創建他/她的配置文件後,掃描您的存儲以獲取具有相同SessionID的圖片。例如,將兩者綁定在一起(例如,將文件ID與配置文件ID關聯起來)。例如,更復雜的過程將包括一個「配置文件創建」cookie,其中應包含專用ID,因此如果用戶放棄該會話並稍後返回上傳的文件仍然可以使用。

  • 執行「垃圾回收器」。達到閾值後的未使用的文件處理(時間或其他)。

我知道這些建議並不完全覆蓋你原來的要求,但他們可能有助於簡化您的實現。