溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ASP.NET MVC深入了解文件上傳的示例分析

發(fā)布時(shí)間:2021-09-22 09:34:06 來源:億速云 閱讀:132 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹ASP.NET MVC深入了解文件上傳的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

深入上傳
再次聲明對(duì)于上傳可以顯示上傳進(jìn)度之類我們不去做過多探討,有這樣的組件,自行去找,我們只需實(shí)現(xiàn)比較核心的這一塊即可。

我們可以想象這一樣一個(gè)場景:比如在博客園中,每個(gè)博客者都可以上傳文件如圖片、腳本之類,我們可以通過園友名稱來創(chuàng)建每個(gè)園友上傳的文件,接下來我們來實(shí)現(xiàn)這樣的一個(gè)場景。

既然是對(duì)應(yīng)博客的名稱創(chuàng)建文件,也就是需要對(duì)應(yīng)的博客這樣的一個(gè)類。如下:

 public class BlogSample
 {
  public string UserName { get; set; }

  public string Id { get; set; }
 }

我們通過博客名稱來創(chuàng)建文件夾并在該文件夾下以唯一的Id來創(chuàng)建子文件夾,在該Id文件夾下的附件( atttachment )中存儲(chǔ)上傳的文件。接下來我們需要梳理整個(gè)上傳文件的過程。難道就把要上傳的文件直接到上傳到對(duì)應(yīng)的文件夾嗎,這么做顯然不是最優(yōu)的,當(dāng)有上傳中斷時(shí)則在文件夾創(chuàng)建的文件不是完整的則是垃圾文件,而我們直接先創(chuàng)建一個(gè)臨時(shí)文件,即使上傳失敗我們可以定期清理臨時(shí)文件也就是垃圾文件,若未中斷,上傳完畢時(shí)則將臨時(shí)文件移動(dòng)到我們對(duì)應(yīng)的文件夾中。通過我們實(shí)際下載文件時(shí)很明顯看的出也是這么做的。接下來我們開始進(jìn)行實(shí)現(xiàn)。

(1)我們給出一個(gè)關(guān)于上傳的 UploadManager 靜態(tài)類,我們可以寫死上傳的文件夾名稱或者通過配置文件自定義上傳文件夾名稱。

  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);
  }

上述已經(jīng)表明可以自定義上傳文件夾在配置文件中(給出上傳虛擬路徑),例如如下:

  <!--<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);


     //若上傳文件夾中子文件夾未存在則創(chuàng)建
     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();
     }
     //上傳完畢將臨時(shí)文件移動(dòng)到目標(biāo)文件
     File.Move(tempPath, targetPath);
    }
   }
   catch (Exception)
   {
    // 若上傳出錯(cuò),則刪除上傳到文件夾文件
    if (File.Exists(targetPath))
     File.Delete(targetPath);

    // 刪除臨時(shí)文件
    if (File.Exists(tempPath))
     File.Delete(tempPath);

    return false;
   }
   finally
   {
    // 刪除臨時(shí)文件
    if (File.Exists(tempPath))
     File.Delete(tempPath);
   }
   return true;
  }

(3)循環(huán)讀取流到文件流中

   /// <summary>
  /// 循環(huán)讀取流到文件流中
  /// </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)開始寫入測試數(shù)據(jù),進(jìn)行調(diào)用方法:

   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();
   }

接下來我們來進(jìn)行測試,通過上傳一個(gè)84M的文件來看看效果(稍等片刻,文件有點(diǎn)大)。

ASP.NET MVC深入了解文件上傳的示例分析

不好意思,令我大失所望,和昨天出現(xiàn)的錯(cuò)誤不一樣,今天出錯(cuò)是:超過最大請(qǐng)求長度。我們接下來再來看看昨天所說,我的IIS為10.0,也就是在IIS 7+上,通過昨天那樣設(shè)置應(yīng)該是沒問題的,難道和另外一個(gè)設(shè)置有關(guān)嗎,我們看看配置文件中的配置。

<httpRuntime targetFramework="4.5"/>
未進(jìn)行設(shè)置,超過其默認(rèn)設(shè)置28.6M就出錯(cuò)了嗎,我們?cè)僭O(shè)置為2G看看。

<httpRuntime targetFramework="4.5" executionTimeout="1100"  maxRequestLength="2147483647"/>

ASP.NET MVC深入了解文件上傳的示例分析

好,上傳成功也未出現(xiàn)上述錯(cuò)誤。

結(jié)語
這一節(jié)我們講了一下利用流來進(jìn)行大文件的處理,不過還是出現(xiàn)了一點(diǎn)小問題,和昨天再一起做一次總結(jié):

(1)在IIS 5和IIS 6中,默認(rèn)文件上傳的最大為4兆,當(dāng)上傳的文件大小超過4兆時(shí),則會(huì)得到錯(cuò)誤信息,但是我們通過如下來設(shè)置文件大小。

<system.web>
 <httpRuntime maxRequestLength="2147483647" executionTimeout="100000" />
</system.web>

(2)在IIS 7+,默認(rèn)文件上傳的最大為28.6兆,當(dāng)超過其默認(rèn)設(shè)置大小,同樣會(huì)得到錯(cuò)誤信息,但是我們卻可以通過如下來設(shè)置文件上傳大?。ㄍ瑫r(shí)也要進(jìn)行如上設(shè)置)。

<system.webServer>
 <security>
 <requestFiltering>
  <requestLimits maxAllowedContentLength="2147483647" />
 </requestFiltering>
 </security>
</system.webServer>

以上是“ASP.NET MVC深入了解文件上傳的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI