1. 程式人生 > >.net mvc web api上傳圖片/檔案並重命名

.net mvc web api上傳圖片/檔案並重命名

寫這個上傳圖片也是耗時好久,以前在asp.net的時候因為自己寫前臺加後臺。後臺也很簡單的就能拿到資料,不做多少判斷。直到現在寫專案,才感覺當初多差,在此告誡下大家寫程式碼時該做的判斷,自己儘可能去完善邏輯與錯誤判斷。
這個專案是拿.net mvc web api寫的後臺,android寫的客戶端。
上傳檔案的大體思路在從http傳輸的資料域中拿到2進位制資料,並儲存下來
廢話不多說,程式碼附上:

#region 上傳圖片
        /// <summary>
        /// 上傳圖片到伺服器  當error為0時成功,為1時失敗 並從errmsg獲取訊息
        ///
</summary>
/// <returns></returns> public Task<Hashtable> post() { String PhoneId = null; // 檢查是否是 multipart/form-data if (!Request.Content.IsMimeMultipartContent("form-data")) throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); //檔案儲存目錄路徑
//string SaveTempPath = "~/App_Data/"; //System.String dirTempPath = HttpContext.Current.Server.MapPath(SaveTempPath); System.String dirTempPath = @"C:\picture"; // 設定上傳目錄 var provider = new MultipartFormDataStreamProvider(dirTempPath); //var queryp = Request.GetQueryNameValuePairs();//獲得查詢字串的鍵值集合
//接受資料並儲存檔案 var task = Request.Content.ReadAsMultipartAsync(provider). ContinueWith<System.Collections.Hashtable>(o => { Hashtable hash = new Hashtable(); hash["error"] = 1; hash["errmsg"] = "上傳出錯"; var file = provider.FileData[0];//provider.FormData string orfilename = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"'); FileInfo fileinfo = new FileInfo(file.LocalFileName); //判斷拿到的PhoneId PhoneId = provider.FormData["PhoneId"]; if (string.IsNullOrEmpty(PhoneId.Trim()) || PhoneId.Trim().Length == 0) { hash["error"] = 1; hash["errmsg"] = "未上傳PhoneId"; fileinfo.Delete(); //如果不寫這句你會發現 返回的資料是正常的 但檔案依舊會Down下來 return hash; } //最大檔案大小 int maxSize = 10000000; if (fileinfo.Length <= 0) { hash["error"] = 1; hash["errmsg"] = "請選擇上傳檔案。"; fileinfo.Delete(); return hash; } else if (fileinfo.Length > maxSize) { hash["error"] = 1; hash["errmsg"] = "上傳檔案大小超過限制。"; fileinfo.Delete(); return hash; } else { string fileExt = orfilename.Substring(orfilename.LastIndexOf('.')); //定義允許上傳的副檔名 String fileTypes = "gif,jpg,jpeg,png,bmp"; if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(fileTypes.Split(','), fileExt.Substring(1).ToLower()) == -1) { hash["error"] = 1; hash["errmsg"] = "上傳副檔名是不允許的副檔名。"; fileinfo.Delete(); return hash; } else { string path = @"picture\" + PhoneId + ".jpg"; try { if (modelusers.updatePicture(PhoneId, path) != 1) { hash["error"] = 1; hash["errmsg"] = "更新資料庫失敗"; fileinfo.Delete(); return hash; } } catch (Exception ex) { hash["error"] = 1; hash["errmsg"] = "更新資料庫失敗2"; fileinfo.Delete(); return hash; } String ymd = DateTime.Now.ToString("yyyyMMdd", System.Globalization.DateTimeFormatInfo.InvariantInfo); //String newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff", System.Globalization.DateTimeFormatInfo.InvariantInfo); String newFileName = PhoneId; fileinfo.CopyTo(Path.Combine(dirTempPath, newFileName + fileExt), true); fileinfo.Delete(); hash["error"] = 0; hash["errmsg"] = "上傳成功"; } } return hash; }); return task; } #endregion

值得注意的幾點:
- 當上傳成功時,error值為0。失敗時,error為1並從errmsg中獲取失敗訊息。
- 在檔案路徑處偷了個懶直接把檔案的路徑塞上去了,如果是從當前路徑下放檔案的話,請遵循註釋。
- PhoneId = provider.FormData[“PhoneId”];這句拿到你應該上傳的檔名,根據你的需求修改
- 如果不進行重新命名的話,檔案會有預設命名值,並且沒有後綴名。這是因為MVC4.0 WebAPI上傳後的圖片預設以字串bodypart結合Guid來命名,且沒有檔案字尾
- fileinfo.Delete();如果不寫這句你會發現 返回的資料是失敗的 但檔案依舊會Down下來 這是因為檔案在一開始執行的時候就已經儲存下來了,所以在失敗後你應該將他刪除。

接下來是我自己寫的簡單測試程式碼,各位再寫完介面時要自己多測試測試,塞一些異常資料進去,看看是否能夠正常執行,不要等到後期出問題了再反過頭去修改。

<html>

    <form action="這裡寫介面url" method="post"  enctype="multipart/form-data">

        <input type="file" name="file">

        <hr>
        <input type="text" name="PhoneId" id="PhoneId">
        <hr>
        <input type="submit" value="submit" id="btnPutUserInfo">


     </form> 
</html>