2016-05-24 4 views
0

Короче говоря, мне нужно отправить массив byte[] в качестве значения body. Проблема в том, что [FromBody] всегда имеет значение null. Все решения, которые я видел до сих пор, включают в себя переданное значение, которое так или иначе переходит в строку. Это нормально, если исходный контент передается простым текстом (ascii), но в случаях, когда я отправляю (например) jpg, это не работает.Как использовать WebClient для POST для WebAPI с помощью [FromBody]

Очень важно понимать и знать, что я НЕ МОГУ использовать HTTPClient, поскольку добавление его в любой форме по какой-то причине нарушает решение во всех местах. Я застрял с помощью WebClient.

Вот код, у меня ниже:

Calling страница:

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 

Что бы разумное решение, так что массив не будет преобразован к строке (которая имеет эффект «развращения» значений)?

+0

Почему бы вам не ввести тип параметра «значение» в поток, а затем преобразовать его в байт в api? – TusharJ

+0

Проблема заключалась в том, что параметр FromBody всегда был нулевым, и получение его из объекта запроса возвращало строку, и это вызывает проблемы с байтовым массивом, если источник не является простым текстом (например, jpg). В любом случае, я понял это и ответил ответ. – MetalPhoenix

ответ

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

Вы не думаете отправки данных в URL, как вы» d записывать в файл, потому что вы просто не делаете так, как это делается, но он работает, и поток байтов не преобразуется в строку в любом месте процесса (который не позволяет потоку быть «поврежденным», если источник не равнина ascii.

Конечно, большая проблема заключается в том, что независимо от того, как вы настроили действие WebAPI для возврата данных, метод OpenWrite ничего не возвращает. Так что все, что вы можете сделать, это выбросить исключение, если что-то пробит. Если вам нужны данные, вам просто нужно написать еще одно действие для извлечения данных, созданных с вашего первого вызова (в этом случае уникальный идентификатор для загруженного и сохраненного файла).

Смежные вопросы