Как правильно получить байт-массив из метода Web Api в С#?
У меня есть следующий метод контроллера:
[HttpPost]
[Route("SomeRoute")]
public byte[] MyMethod([FromBody] string ID)
{
byte[] mybytearray = db.getmybytearray(ID);//working fine,returning proper result.
return mybytearray;
}
Теперь в вызывающем методе (это также другой метод WebApi!) Я написал вот так:
private HttpClient client = new HttpClient ();
private HttpResponseMessage response = new HttpResponseMessage ();
byte[] mybytearray = null;
response = client.GetAsync(string.Format("api/ABC/MyMethod/{0}", ID)).Result;
if (response.IsSuccessStatusCode)
{
mybytearray = response.Content.ReadAsByteArrayAsync().Result;//Here is the problem
}
Теперь проблема состоит в том, что массив байтов MyMethod
отправляет 528 байт, но здесь после создания ReadAsByteArrayAsync
размер становится больше (706 байт), и значения также искажаются.
Вид ударяет головой об этом, любая помощь будет оценена.
Благодарю!
Ответы
Ответ 1
HTTP - это текстовый протокол. edit: HTTP также может передавать необработанные байты. Luaan ответ лучше.
Возвращенный массив байтов будет каким-то образом преобразован в текст, в зависимости от того, как MediaTypeFormatterCollection
настроен на сервере и в формате, запрошенном клиентом HTTP, с заголовком Accept
. Обычно байты преобразуются в текст с помощью кодирования base64. Ответ также может быть дополнительно упакован в JSON или XML, но отношение ожидаемой длины (528) к фактической длине (706), по-видимому, указывает на простую строку base64.
На стороне клиента вы не смотрите на исходные байты, а на байты этого текстового представления. Я бы попробовал прочитать данные в виде строки с помощью ReadAsStringAsync
и проверить ее, чтобы посмотреть, в каком формате она находится. Также посмотрите на заголовки ответа.
Затем вы должны проанализировать этот текст, чтобы получить исходные байты, например, с Convert.FromBase64String.
Ответ 2
Фактически, HTTP также может обрабатывать "необработанный" двоичный файл - сам протокол является текстовым, но полезная нагрузка может быть двоичной (см. Все файлы, которые вы загружаете из Интернета, используя HTTP).
В WebApi есть способ сделать это - вам просто нужно использовать StreamContent
или ByteArrayContent
в качестве контента, поэтому он требует некоторой ручной работы:
public HttpResponseMessage ReturnBytes(byte[] bytes)
{
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(bytes);
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
Возможно, можно сделать то же самое, используя какой-то атрибут или что-то в этом роде, но я не знаю, как это сделать.
Ответ 3
response.Content.ReadAsAsync<byte[]>().Result//Put this code in your client.
Я хочу прояснить, что ReadAsAsync<byte[]>()
и ReadAsByteArrayAsync()
НЕ действуют одинаково.
ReadAsByteArrayAsync() превращает все в байтовый массив Base64. Он не получает не Base64 byte[]
из response.Content, но ReadAsAsync<byte[]>()
делает
Ответ 4
Вместо этого
mybytearray = response.Content.ReadAsByteArrayAsync().Result;//Here is the problem
Использовать это
string result=null;
result = response.Content.ReadAsStringAsync().Result.Replace("\"", string.Empty);
mybytearray=Convert.FromBase64String(result);
ответ возвращал массив байтов как base64encoded.
Ответ 5
От конца WEBAPI/Server передайте значения как:
String base64 = Convert.ToBase64String(bytes); //Convert to ToBase64String
и получить значения от клиента
response = client.GetAsync("URL/home/GetFIle?id=" + File_id).Result;
responseBody = await response.Content.ReadAsStringAsync();
mybytearray = Convert.FromBase64String(responseBody); //Convert to FromBase64String