如何在OWIN管道上的web api 2中接收multipart/form-data

问题描述:

我无法让我的web api 2方法在角度用户界面上从ng-file-upload正确读取我的multipart/form-data文章侧。如何在OWIN管道上的web api 2中接收multipart/form-data

我发起呼叫,像这样:

Upload.upload({ 
       url: config.ApiUrl + 'Orders/CreateOrder', 
       data: request 
      }).then(function (response) { 
       console.log('Success ' + response.config.data.file.name + 'uploaded. Response: ' + response.data); 
      }, function (error) { 
       $scope.errors = "Oops! Something went wrong... " + error.statusText; 
      }); 

这让我的有效载荷发送到网络API:

-----------------------------9623122368016 
Content-Disposition: form-data; name="somefield" 

Some Value 
-----------------------------9623122368016 
Content-Disposition: form-data; name="errorMessage" 

null 
-----------------------------9623122368016 
Content-Disposition: form-data; name="success" 

false 
-----------------------------9623122368016 
Content-Disposition: form-data; name="file"; filename="imapdf.pdf" 
Content-Type: application/pdf 

%PDF-1.2 
1 0 obj 
<< 
/Producer() 
/Author() 
/Title() 
/Subject() 
/Keywords() 
/CreationDate(D:20040106) 
/ModDate(D:20040106) 
/Creator() 
>> 
endobj 
2 0 obj 
<< 
/Type/XObject 
/Subtype/Image 
/Name/wpt1 
/Width 41 
/Height 15 
/BitsPerComponent 8 
/ColorSpace/DeviceRGB 
/Length 100 
/Filter [/FlateDecode] >> 
stream 
xsqH0s 

我无法访问HttpContext.Current.Request.Files因为我使用OWIN管道,并没有太多运气Request.Content.ReadAsMultipartAsync

我怎样才能接收我的文件&它与web api 2中的表单数据相关联?

C#代码更新:

public Task<OrderRequest> CreateOrder(OrderRequest orderRequest) 
{ 
    try 
    { 
     var asdf = OwinHttpRequestMessageExtensions.GetOwinContext(Request); 
     if (!Request.Content.IsMimeMultipartContent("multipart/form-data")) 
     { 
      var provider = new MultipartMemoryStreamProvider(); 
      this.Request.Content.ReadAsMultipartAsync(provider); 

      var content = provider.Contents.First(); 
      var buffer = content.ReadAsByteArrayAsync(); 
     } 

     var test = orderRequest; 
     var a = HttpContext.Current.Request.Files; 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 

    return Task.FromResult<OrderRequest>(null); 
} 
+0

它看起来像AngularJS代码正确创建HTTP请求。请显示有问题的服务器端代码。 – georgeawg

+0

@georgeawg张贴我无意中获得的数据 – RandomUs1r

+0

看来你需要使用'Request.Content.ReadAsMultipartAsync'。你能告诉我们你的代码吗? –

顾名思义,ReadAsMultipartAsync异步功能。由于您没有在等待电话,因此您可能最终会在您尝试访问Contents之前填充该电话。

为了解决这个问题,你可以按以下步骤更新您的CreateOrder行动:

public async Task<OrderRequest> CreateOrder(OrderRequest orderRequest) 
{ 
    ... 
    await this.Request.Content.ReadAsMultipartAsync(provider); 
    ... 
} 

所有这一切在这里改变是增加了asyncthis.Request.Content.ReadAsMultipartAsync(provider);之前Task<OrderRequest>await之前。由于相同的原因,您还需要在content.ReadAsByteArrayAsync();之前添加await,然后您可以只使用return null,而不必在最后使用Task.FromResult

事实上,这里的这些变化对整个代码:

public async Task<OrderRequest> CreateOrder(OrderRequest orderRequest) 
{ 
    try 
    { 
     var asdf = OwinHttpRequestMessageExtensions.GetOwinContext(Request); 
     if (!Request.Content.IsMimeMultipartContent("multipart/form-data")) 
     { 
      var provider = new MultipartMemoryStreamProvider(); 
      await this.Request.Content.ReadAsMultipartAsync(provider); 

      var content = provider.Contents.First(); 
      var buffer = await content.ReadAsByteArrayAsync(); 
     } 

     var test = orderRequest; 
     var a = HttpContext.Current.Request.Files; 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 

    return null; 
} 

显然,这不是一个完整的解决方案,但我相信它会满足您的具体问题,并允许你继续探索。

+0

这很有道理,感谢您的帮助! – RandomUs1r