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

时间:2017-09-20 17:50:51

标签: c# angularjs asp.net-web-api2 owin multipartform-data

我无法使用我的web api 2方法在角度UI端从ng-file-upload正确读取我的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;
            });

这会给我一个有效载荷发送到web 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

运气不佳

我如何收到我的档案&amp;它是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);
}

1 个答案:

答案 0 :(得分:1)

顾名思义,ReadAsMultipartAsync是一个异步函数。由于您没有等待通话,因此您最终可能会在填充之前尝试访问Contents

要解决此问题,您可以按照以下步骤更新CreateOrder操作:

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

此处所做的更改是在async之前添加Task<OrderRequest>,在await之前添加this.Request.Content.ReadAsMultipartAsync(provider);。出于同样的原因,您还需要在await之前添加content.ReadAsByteArrayAsync();,然后您可以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;
}

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