文章目錄
ASP.NET Web API 上傳檔案出現 415 Unsupported Media Type 錯誤
最近專案前端高互動性的頁面採用 Vue.js 來呈現,讓原本習慣的開發流程跟方式都需求做些調整,像是 Vue.js 存取資料部份因為沒有 server render html 的需要就使用 Web API 來處理,當然過程中小問題不斷,其中一個就是透過 Vue.js 上傳檔案時遇到 415 Unsupported Media Type 的錯誤,所以紀錄一下解決方式,畢竟日後前後端拆分開發的機會應該會更多
錯誤訊息
訊息內容
{ "Message": "The request entity's media type 'multipart/form-data' is not supported for this resource.", "ExceptionMessage": "No MediaTypeFormatter is available to read an object of type 'HttpPostedFileBase' from content with media type 'multipart/form-data'.", "ExceptionType": "System.Net.Http.UnsupportedMediaTypeException", "StackTrace": " at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)" }
錯誤截圖
解決方式一:從 HttpContext 中取得檔案
api 程式碼
public class UploadController : ApiController { public HttpResponseMessage Post() { //取得當前的 request 物件 var httpRequest = HttpContext.Current.Request; //request 如有夾帶檔案 if (httpRequest.Files.Count > 0) { //逐一取得檔案名稱 foreach (string fileName in httpRequest.Files.Keys) { //以檔案名稱從 request 的 Files 集合取得檔案內容 var file = httpRequest.Files[fileName]; //其他檔案處理 } return Request.CreateResponse(HttpStatusCode.OK); } return Request.CreateResponse(HttpStatusCode.BadRequest); } }
前端上傳內容
- Content-Type:application/x-www-form-urlencoded
body 夾檔
順利取得檔案內容
解決方式二:使用 MultipartFormDataStreamProvider
API 程式碼
public class UploadController : ApiController { public HttpResponseMessage Post() { // 如果 Content-Type 沒有 multipart/form-data 就回傳 415 if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } //檔案儲存路徑 string root = HttpContext.Current.Server.MapPath("~/App_Data"); //建立 MultipartFormDataStreamProvider instance var provider = new MultipartFormDataStreamProvider(root); try { //從 request content 中讀取檔案並以 BodyPart_{GUID} 格式寫至上方定義的路徑中 Request.Content.ReadAsMultipartAsync(provider); // 取得實際檔案內容 foreach (MultipartFileData file in provider.FileData) { //實際檔案處理 } return Request.CreateResponse(HttpStatusCode.OK); } catch (System.Exception e) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e); } } }
前端上傳內容
Content-Type:multipart/form-data
使用 postman 時只要上傳內容選擇
file
會自動加上multipart/form-data
body 夾檔
心得
ASP.NET WebApi: MultipartDataMediaFormatter 這篇文章有提到如果使用 HttpClient 上傳至 Web API 可以透過安裝套件來解決,有需要請自行參閱(與今天主題有些落差就不特別介紹,日後若有用到再另文紀錄)
話說今天紀錄的內容滿虛的:一來是發生原因不是很肯定(個人不負責任推測是 Web API 底層實作與 MVC 不同有關 );二來是方法二用到的 MultipartFormDataStreamProvider
看了一些文件仍然未全然掌握用途,不過沒關係相信有天實力增強時應該就有契機可以學得透徹些了
參考資訊
文章作者 Yowko Tsai
上次更新 2021-11-03
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。