標籤:
該樣本中實際上應用了 jquery ajax(web client) + async web api 雙非同步。
jquery ajax post
1 $.ajax({ 2 type: "POST", 3 url: "/api/FileUpload", 4 contentType: false, 5 processData: false, 6 data: data, 7 success: function (results) { 8 ShowUploadControls(); 9 $("#uploadResults").empty();10 for (i = 0; i < results.length; i++) {11 $("#uploadResults").append($("<li/>").text(results[i]));12 }13 },14 error: function (xhr, ajaxOptions, thrownError) {15 ShowUploadControls();16 alert(xhr.responseText);17 }18 });
client端以post的方式發送資料。其中上傳成功後的回調指令碼定義在success處。
async Web API
Controller處Action傳回值為Task<TResult>,本例中如下定義:
1 public Task<IEnumerable<string>> Post()2 {3 ... ... 4 }
而具體非同步效果體現在“檔案內容讀取”和“後續處理”上。
1 string fullPath = HttpContext.Current.Server.MapPath("~/Uploads"); 2 CustomMultipartFormDataStreamProvider streamProvider = new CustomMultipartFormDataStreamProvider(fullPath); 3 var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t => 4 { 5 if (t.IsFaulted || t.IsCanceled) 6 throw new HttpResponseException(HttpStatusCode.InternalServerError); 7 8 var fileInfo = streamProvider.FileData.Select(i => 9 {10 var info = new FileInfo(i.LocalFileName);11 return "File saved as " + info.FullName + " (" + info.Length + ")";12 });13 return fileInfo;14 15 });
ReadAsMultipartAsync
(From MSDN) 讀取 MIME 多部分訊息中的所有本文部分,並通過使用 streamProvider 執行個體確定每個本文部分內容的寫入位置,來產生一組 HttpContent 執行個體作為結果。
Task.ContinueWith<TResult>
建立一個在目標 Task 完成時非同步執行的延續任務。具體到該樣本中,當 ReadAsMultipartAsync(讀取)任務完成後,ContinueWith 中定義的行為才會作為延續而非同步執行。
MultipartFormDataStreamProvider 對象
一個 IMultipartStreamProvider,適合與 HTML 檔案上傳一起使用,以將檔案內容寫入 FileStream。流提供者將查看 <b>Content-Disposition</b> 標題欄位,並根據 <b>filename</b> 參數是否存在來確定輸出 Stream。如果 <b>Content-Disposition</b> 標題欄位中存在 <b>filename</b> 參數,則本文部分將寫入 FileStream 中;否則,本文部分將寫入 MemoryStream 中。這將更加便於處理作為表單資料和檔案內容的組合的 MIME 多部分 HTML 表單資料。
小技巧:lambda 運算式反轉,從FileData到IEnumerable<string>
1 var fileInfo = streamProvider.FileData.Select(i =>2 {3 var info = new FileInfo(i.LocalFileName);4 return "File saved as " + info.FullName + " (" + info.Length + ")";5 });
範例程式碼
ASP.NET 非同步Web API + jQuery Ajax 檔案上傳代碼小析