ASP.NET 異步Web API + jQuery Ajax 文件上傳代碼小析

該示例中實際上應用了 jquery ajax(web client) + async web api 雙異步。jquery

jquery ajax postweb

 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處。ajax

 

async Web APIapi

Controller處Action返回值爲Task<TResult>,本例中以下定義:app

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

ReadAsMultipartAsyncasync

(From MSDN) 讀取 MIME 多部分消息中的全部正文部分,並經過使用 streamProvider 實例肯定每一個正文部份內容的寫入位置,來生成一組 HttpContent 實例做爲結果。ide

 


Task.ContinueWith<TResult>post

建立一個在目標 Task 完成時異步執行的延續任務。具體到該示例中,當 ReadAsMultipartAsync(讀取)任務完成後,ContinueWith 中定義的行爲纔會做爲延續而異步執行。url

 

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

 

示例代碼

相關文章
相關標籤/搜索