2016-03-07 45 views
0

我想將文件異步發佈到服務器而不發佈表單。我有以下代碼:AJAX:將文件異步發佈到服務器

var fileInput = document.getElementById('FileInput'); 
var file = fileInput.files[0]; 
var formData = new FormData(); 
formData.append('file', file, file.name); 
var xhr = new XMLHttpRequest(); 
xhr.open('POST', 'http://servername/controllername/AnalyseFile', true); 
xhr.setRequestHeader('Content-Type', 'multipart/form-data'); 
xhr.send(formData); 

然而,當在服務器上執行的方法,後身體不包含任何文件。以下是來自ASP.NET MVC4:

[HttpPost] 
public JsonResult AnalyseFile() 
{ 
    int filesCount = Request.Files.Count; 
    if(filesCount == 0) { throw new Exception('no files...'); } 
    // do stuff 
} 

Files集合不包含文件,我找不出原因。任何幫助讚賞。

+0

雖然可以不使用表格上傳文件,但爲什麼要這麼做呢?如果要將完整頁面的帖子保存回來,則可以僅使用部分表單。以下是一個示例:http://stackoverflow.com/questions/21675176/asp-net-mvc3-upload-a-file-from-a-partial-view-and-fill-the-corresponding-field – wazdev

+0

http:// stackoverflow.com/questions/15680629/mvc-4-razor-file-upload –

+0

@wazdev我不想提交表格,我想搶先上傳文件,而用戶仍然在他們的工作瀏覽器並使用它做一些事情並將結果返回給瀏覽器。再次,我想要做的就是將文件自行異步發送到服務器,並讓服務器將一些關於該文件的元數據返回給我將動態顯示的瀏覽器。 –

回答

0

您需要從請求中讀取MultiPartFormData。

按本post

你的方法是這個樣子:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Web.Http; 

namespace Some.Namespace 
{ 
    public class SomeController : ApiController 
    { 
     [HttpPost] 
     public async Task<JsonResult> AnalyseFile() 
     { 
      if (!Request.Content.IsMimeMultipartContent()) 
      { 
       //If not throw an error 
       throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 
      } 

      MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider("c:\\tmp\\uploads"); 

      // Read the MIME multipart content using the stream provider we just created. 
      IEnumerable<HttpContent> bodyparts = await Request.Content.ReadAsMultipartAsync(streamProvider); 

      // Get a dictionary of local file names from stream provider. 
      // The filename parameters provided in Content-Disposition header fields are the keys. 
      // The local file names where the files are stored are the values. 
      //depending on your version of .net, this might have been changed to FileData instead. 
      // see: https://msdn.microsoft.com/en-us/library/system.net.http.multipartformdatastreamprovider(v=vs.118).aspx 
      IDictionary<string, string> bodyPartFileNames = streamProvider.BodyPartFileNames; 

      //rest of code here 

    } 
} 

我沒有測試上面的代碼,但它應該指向你在正確的方向。

也看看How To Accept a File POST

對於一個更近的文章:https://code.msdn.microsoft.com/AngularJS-with-Web-API-22f62a6e

+0

這是否仍然需要POST的表單 - 因此「multipart/form-data」? – wazdev

+0

您將執行「POST」類型的請求,並將負載設置爲文件,並將內容類型設置爲multipart/form數據。實際上,您正在發佈表單的一部分,但沒有進行適當的表單發佈。 – JanR

+0

這是WebAPI能夠接受文件的標準設置。如果你想做一個實際的表單帖子,你只需發佈到控制器而不是api。 – JanR

1

在視圖,你可以這樣做:

<form> 
<input name="input1" id="input1"/> 
<input name="input2" id="input2"/> 
<input name="input3" id="input3"/> 
... 
<input id="SelectedFile" name="SelectedFile" type="file"/> 
</form> 

和Javascript:

function AttLogic(_url, _data, _callback) { 
    $.ajax({ 
     url: _url, 
     type: 'POST', 
     xhr: function() { 
      var myXhr = $.ajaxSettings.xhr(); 
      if (myXhr.upload) { } 
      return myXhr; 
     }, 
     data: _data, 
     cache: !1, 
     success: _callback, 
     contentType: !1, 
     processData: !1 
    }); 
} 

function FormDataCustom(f) { 
    var __frm = jQuery(f), data = new FormData(f); 
    $(':disabled[name]', __frm).each(function() { 
     data.append(this.name, $(this).val()); 
    }); 
    return data; 
} 

function SaveLogic(){ 
var dt = FormDataCustom(document.forms[0]); 
AttLogic(yourUrl, dt, function (r) { 
     //do something here 
    }); 
} 

在控制器中:

public ActionResult Save(parameter1,parameter1,..., List<HttpPostedFileBase> SelectedFile) 
{ 
    //do something here 
} 
相關問題