【问题标题】:How to use WebClient to POST to WebAPI using [FromBody]如何使用 [FromBody] 使用 WebClient POST 到 WebAPI
【发布时间】:2016-05-24 20:55:40
【问题描述】:

简而言之,我需要发送一个 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

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

【问题讨论】:

  • 为什么不将“value”参数类型设置为流式传输,然后在 api 中将其转换为字节?
  • 问题是因为 FromBody 参数始终为空,从请求对象中获取它会返回一个字符串,如果源不是纯文本(如 jpg),这会导致字节数组出现问题.无论如何,我想通了并发布了答案。

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


【解决方案1】:

这个问题的解决方案是违反直觉的:

//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(); 

您不会以写入文件的方式将数据发送到 URL,因为您只是不这样做,但它可以工作并且字节流不会被转换在进程中的任何位置进入字符串(如果源不是纯 ascii,则可以防止流被“损坏”。

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

【讨论】:

    猜你喜欢
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 2012-10-18
    相关资源
    最近更新 更多