如何使用WebClient使用[FromBody] POST到WebAPI

时间:2016-05-24 20:55:41

标签: c# vb.net post asp.net-web-api2 webclient

缺点是我需要发送byte[]数组作为正文值。问题是[FromBody]始终为空。到目前为止,我所看到的所有解决方案都涉及以某种方式传递给字符串的值。如果传递的原始内容是纯文本(ascii),但是在我发送(例如)jpg的情况下这没有用,这是行不通的。

非常重要的是要意识到并且知道我不能使用HTTPClient,因为某种原因在任何形式下添加它都会破坏各种地方的解决方案。我被困在使用WebClient。

以下是我的代码:

致电页面:

Private Function UploadFile(targetURL As String, fileAttachment As Byte()) As String
    Dim retVal As String = String.Empty
    Using client = New WebClient()
        Try                
            Dim request As HttpWebRequest = DirectCast(WebRequest.Create(targetURL), HttpWebRequest)
            request.Method = "POST"
            request.ContentType = "application/x-www-form-urlencoded"
            request.ContentLength = fileAttachment.Length

            Dim requestStream As Stream = request.GetRequestStream()
            requestStream.Write(fileAttachment, 0, fileAttachment.Length)

            Dim response As WebResponse = request.GetResponse()
            Dim respStream As Stream = response.GetResponseStream()
            Dim reader As New StreamReader(respStream)

            retVal = reader.ReadToEnd()
            respStream.Dispose()
            reader.Dispose()
        Catch ex As WebException
            If ex.Status = WebExceptionStatus.ProtocolError Then
                Dim wbrsp As HttpWebResponse = CType(ex.Response, HttpWebResponse)
                Throw New HttpException(CInt(wbrsp.StatusCode), wbrsp.StatusDescription)
            Else
                Throw New HttpException(500, ex.Message)
            End If
        End Try
    End Using
    Return retVal
End Function

WebAPI方法:

    [Route("Upload/{appName}/{appKey}/{fileName}/{fileExt}")]
    public async Task<string> Post(string appName, string appKey, string fileName, string fileExt, [FromBody] byte[] values) { 
//snip as rest is not needed since values is always null

什么是合理的解决方案,以便字节数组不会转换为字符串(具有“破坏”值的效果)?

1 个答案:

答案 0 :(得分:0)

对此的解决方案是违反直觉的:

//targetURL As String, fileAttachment As Byte(), fileName As String, fileExtension As String
//you don't send the data to the webapi action. You WRITE to it like it's a file        
Using client = New WebClient()
    Try
        client.Headers.Add("Content-Type", "application/octet-stream")
        Using requestStream As Stream = client.OpenWrite(New Uri(targetURL), "POST")
            requestStream.Write(fileAttachment, 0, fileAttachment.Length)
        End Using    
    Catch ex As WebException
        If ex.Status = WebExceptionStatus.ProtocolError Then
            Dim wbrsp As HttpWebResponse = CType(ex.Response, HttpWebResponse)
            Throw New HttpException(CInt(wbrsp.StatusCode), wbrsp.StatusDescription)
        Else
            Throw New HttpException(500, ex.Message, New Exception("File upload failed."))
        End If
    End Try
End Using

WebAPI的神奇代码:

byte[] values = await Request.Content.ReadAsByteArrayAsync(); 

您不会想到以您写入文件的方式将数据发送到网址,因为您只是不做那样的事情但它有效并且字节流不会在进程中的任何位置转换为字符串(这使得流不会被#34;损坏&#34;如果源不是简单的ascii。

当然,最大的问题是,无论您如何设置WebAPI操作来返回数据,OpenWrite方法都不会返回任何内容。所以你所能做的就是抛出异常,如果有什么事情发生的话。如果您需要返回数据,您只需编写另一个操作来检索从第一次调用创建的数据(在这种情况下,上传和保存文件的唯一ID)。