您好,登錄后才能下訂單哦!
這篇文章主要介紹ASP.NET MVC深入了解文件上傳的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
深入上傳
再次聲明對于上傳可以顯示上傳進度之類我們不去做過多探討,有這樣的組件,自行去找,我們只需實現比較核心的這一塊即可。
我們可以想象這一樣一個場景:比如在博客園中,每個博客者都可以上傳文件如圖片、腳本之類,我們可以通過園友名稱來創建每個園友上傳的文件,接下來我們來實現這樣的一個場景。
既然是對應博客的名稱創建文件,也就是需要對應的博客這樣的一個類。如下:
public class BlogSample { public string UserName { get; set; } public string Id { get; set; } }
我們通過博客名稱來創建文件夾并在該文件夾下以唯一的Id來創建子文件夾,在該Id文件夾下的附件( atttachment )中存儲上傳的文件。接下來我們需要梳理整個上傳文件的過程。難道就把要上傳的文件直接到上傳到對應的文件夾嗎,這么做顯然不是最優的,當有上傳中斷時則在文件夾創建的文件不是完整的則是垃圾文件,而我們直接先創建一個臨時文件,即使上傳失敗我們可以定期清理臨時文件也就是垃圾文件,若未中斷,上傳完畢時則將臨時文件移動到我們對應的文件夾中。通過我們實際下載文件時很明顯看的出也是這么做的。接下來我們開始進行實現。
(1)我們給出一個關于上傳的 UploadManager 靜態類,我們可以寫死上傳的文件夾名稱或者通過配置文件自定義上傳文件夾名稱。
static UploadManager() { //從配置文件中獲取上傳文件夾 if (String.IsNullOrWhiteSpace(WebConfigurationManager.AppSettings["UploadFolder"])) UploadFolderRelativePath = @"~/upload"; else UploadFolderRelativePath = WebConfigurationManager.AppSettings["UploadFolder"]; UploadFolderPhysicalPath = HostingEnvironment.MapPath(UploadFolderRelativePath); if (!Directory.Exists(UploadFolderPhysicalPath)) Directory.CreateDirectory(UploadFolderPhysicalPath); }
上述已經表明可以自定義上傳文件夾在配置文件中(給出上傳虛擬路徑),例如如下:
<!--<add key="UploadFolder" value="~/UploadFile/">-->
(2)保存文件的核心方法
[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")] public static bool SaveFile(Stream stream, string fileName, string userName, string guid) { string tempPath = string.Empty, targetPath = string.Empty; try { string tempFileName = GetTempFilePath(fileName); if (userName != null) { var contentType = userName; var contentId = guid; tempPath = GetTempFilePath(tempFileName); targetPath = GetTargetFilePath(fileName, contentType, contentId, string.Empty, FilesSubdir); //若上傳文件夾中子文件夾未存在則創建 var file = new FileInfo(targetPath); if (file.Directory != null && !file.Directory.Exists) file.Directory.Create(); using (FileStream fs = File.Open(tempPath, FileMode.Append)) { if (stream.Length > 0) { SaveFile(stream, fs); } fs.Close(); } //上傳完畢將臨時文件移動到目標文件 File.Move(tempPath, targetPath); } } catch (Exception) { // 若上傳出錯,則刪除上傳到文件夾文件 if (File.Exists(targetPath)) File.Delete(targetPath); // 刪除臨時文件 if (File.Exists(tempPath)) File.Delete(tempPath); return false; } finally { // 刪除臨時文件 if (File.Exists(tempPath)) File.Delete(tempPath); } return true; }
(3)循環讀取流到文件流中
/// <summary> /// 循環讀取流到文件流中 /// </summary> /// <param name="stream"></param> /// <param name="fs"></param> public static void SaveFile(Stream stream, FileStream fs) { var buffer = new byte[4096]; int bytesRead; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0) { fs.Write(buffer, 0, bytesRead); } }
(4)開始寫入測試數據,進行調用方法:
var testSample = new BlogSample() { UserName = "xpy0928", Id = Guid.NewGuid().ToString("N") }; if (ModelState.IsValid) { var fileName = bModel.BlogPhoto.FileName; var success = UploadManager.SaveFile(bModel.BlogPhoto.InputStream, fileName, testSample.UserName, testSample.Id); if (!success) { // TODO(your code) } //var filePath = Server.MapPath(string.Format("~/{0}", "File")); //bModel.BlogPhoto.SaveAs(Path.Combine(filePath, fileName)); ModelState.Clear(); }
接下來我們來進行測試,通過上傳一個84M的文件來看看效果(稍等片刻,文件有點大)。
不好意思,令我大失所望,和昨天出現的錯誤不一樣,今天出錯是:超過最大請求長度。我們接下來再來看看昨天所說,我的IIS為10.0,也就是在IIS 7+上,通過昨天那樣設置應該是沒問題的,難道和另外一個設置有關嗎,我們看看配置文件中的配置。
<httpRuntime targetFramework="4.5"/>
未進行設置,超過其默認設置28.6M就出錯了嗎,我們再設置為2G看看。
<httpRuntime targetFramework="4.5" executionTimeout="1100" maxRequestLength="2147483647"/>
好,上傳成功也未出現上述錯誤。
結語
這一節我們講了一下利用流來進行大文件的處理,不過還是出現了一點小問題,和昨天再一起做一次總結:
(1)在IIS 5和IIS 6中,默認文件上傳的最大為4兆,當上傳的文件大小超過4兆時,則會得到錯誤信息,但是我們通過如下來設置文件大小。
<system.web> <httpRuntime maxRequestLength="2147483647" executionTimeout="100000" /> </system.web>
(2)在IIS 7+,默認文件上傳的最大為28.6兆,當超過其默認設置大小,同樣會得到錯誤信息,但是我們卻可以通過如下來設置文件上傳大小(同時也要進行如上設置)。
<system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="2147483647" /> </requestFiltering> </security> </system.webServer>
以上是“ASP.NET MVC深入了解文件上傳的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。