2013-03-18 66 views
2

我使用遍布各处的几个例子中的任何一个用.net Web API做文件上传。文件存储到服务器,但提供者上的fileData对象始终为空。下面的代码。asp.net Web API文件上传fileData空

var url = "api/Documents/fileUpload"; 
        var xhr = new XMLHttpRequest(); 
        var file = document.getElementById("inputFile").files[0]; 
        var formData = new FormData(); 
        formData.append('file', file); 
        xhr.open("POST", url, true); 
        xhr.responseType = "text"; 
        xhr.onreadystatechange = function() { 
         if (xhr.readyState == xhr.DONE) { 
          console.log("photoUpload xhr", xhr); 
          var responseTypeAsJSON = JSON.parse(xhr.responseText); 
          currentPhoto.responseText = xhr.responseText; 
          if (responseTypeAsJSON.result == "SUCCESS") { 
           currentPhoto.status = "SUCCESSfully uploaded"; 
          } 
          else { 
           currentPhoto.status = responseTypeAsJSON.result; 
           alert(responseTypeAsJSON.message); 
          } 
          PhotoClear(); 
          // console.log(currentPhoto); 
          // console.log("xhr done: ", xhr); 

         } 
        } 
        xhr.send(formData); 
        // console.log("xhr sent: ", xhr); 

控制器,用于接收:

 [HttpPost] 
    [ActionName("fileUpload")] 
    public Task<HttpResponseMessage> fileUpload() 
    { 
     HttpRequestMessage request = this.Request; 
     if (!request.Content.IsMimeMultipartContent()) 
     { 
      throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 
     } 

     string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data"); 
     var provider = new MultipartFormDataStreamProvider(root); 

     var task = request.Content.ReadAsMultipartAsync(provider). 
      ContinueWith<HttpResponseMessage>(o => 
      { 

       string file1 = provider.FileData.First().LocalFileName.ToString(); 
       // this is the file name on the server where the file was saved 

       return new HttpResponseMessage() 
       { 
        Content = new StringContent("File uploaded.") 
       }; 
      } 
     ); 
     return task; 
    } 

下面是从浏览器请求。当我调试提供程序时,表单数据的键也是空的。然而,文件被放入AppData的

Request URL:http://localhost:4231/api/Documents/fileUpload 
Request Headersview source 
Content-Type:multipart/form-data; boundary=----WebKitFormBoundarycuGegdEDmBsR0mMl 
Origin:http://localhost:4231 
Referer:http://localhost:4231/ 
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko)  Chrome/25.0.1364.172 Safari/537.22 
Request Payload 
------WebKitFormBoundarycuGegdEDmBsR0mMl 
Content-Disposition: form-data; name="testInfo" 

some info here for testing 
------WebKitFormBoundarycuGegdEDmBsR0mMl 
Content-Disposition: form-data; name="file"; filename="irislogo.png" 
Content-Type: image/png 


------WebKitFormBoundarycuGegdEDmBsR0mMl-- 
+0

嗯..在上面的动作,应该不会有任何问题获取文件名...我知道这并不重要,因为你看到该文件创建,但你能分享你的原始请求是怎么样的,以便我可以尝试重新制作它.. – 2013-03-18 19:39:41

+0

感谢您的请求细节。我无法使用上述请求细节和操作来重新制作它。我能够看到本地文件名属性的值。 – 2013-03-18 20:25:43

+0

这是最奇怪的事情。文件使其进入目录,但Read..Async的任务部分永远不会被执行,因为formdata总是显示为空。 – user2183648 2013-03-18 20:29:37

回答

2

我也陷入了这个确切的问题,也是一个小的代码改变固定的问题。

行:

var provider = new MultipartFormDataStreamProvider(root); 

应该是:

var provider = new MultipartFileStreamProvider(root); 
+0

这解决了我的问题。但我不明白为什么?我发送的数据FormData,它不应该仍然是FormData,而不是文件? – Schoof 2017-02-02 12:09:38

+1

底下,.Net具有在模型绑定过程中将文件与FormData分开的逻辑。这是在WebAPI 2中引入的,因此您可以重写文件处理逻辑以执行直接上载到Azure Blob存储的操作。 有关更深入的了解,请参阅WebAPI生命周期,特别是模型绑定:https://www.asp.net/media/4071077/aspnet-web-api-poster.pdf – rbj325 2017-02-03 15:53:21

0

我也有这个问题;这里是解决方案:

public async Task<HttpResponseMessage> Save() 
{ 
    string root = HttpContext.Current.Server.MapPath("~/App_Data"); 

    var provider = new MultipartFormDataStreamProvider(root); 

    await Request.Content.ReadAsMultipartAsync(provider); 

    // provider.FileData will contain your data... 
    // you can also send form data which will be in provider.FormData 
}