如何从C#中的Web Api方法正确获取字节数组?

use*_*533 34 c# asp.net-web-api

我有以下控制器方法:

[HttpPost]
[Route("SomeRoute")]
public byte[] MyMethod([FromBody] string ID)
{
  byte[] mybytearray = db.getmybytearray(ID);//working fine,returning proper result.
  return mybytearray;
}
Run Code Online (Sandbox Code Playgroud)

现在在调用方法(这也是另一个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
} 
Run Code Online (Sandbox Code Playgroud)

现在,问题是字节数​​组MyMethod发送的是528字节,但是在这之后ReadAsByteArrayAsync,大小变得更大(706字节)并且这些值也被放大了.

有点打击我的头,任何帮助将不胜感激.

谢谢!

Lua*_*aan 74

实际上,HTTP也可以处理"原始"二进制文件 - 协议本身是基于文本的,但有效负载可以是二进制文件(请参阅使用HTTP从Internet下载的所有文件).

有一种方法可以在WebApi中执行此操作 - 您只需使用StreamContentByteArrayContent作为内容,因此它确实涉及一些手动工作:

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;
}
Run Code Online (Sandbox Code Playgroud)

使用某些属性或某事可能会做同样的事情,但我不知道如何做.


Wim*_*nen 12

HTTP是基于文本的协议.编辑:HTTP也可以传输原始字节.Luaan的答案更好.

返回的字节数组将以某种方式转换为文本,具体取决于在MediaTypeFormatterCollection服务器上设置的方式以及HTTP客户端使用Accept标头请求的格式.字节通常将通过base64编码转换为文本.响应也可以进一步打包成JSON或XML,但是预期长度(528)与实际长度(706)的比率似乎表示简单的base64字符串.

在客户端,您不是查看原始字节,而是查看此文本表示的字节.我会尝试将数据作为字符串读取ReadAsStringAsync并检查它以查看它的格式.还要查看响应的标题.

然后,您应该相应地解析此文本以获取原始字节,例如使用Convert.FromBase64String.

  • 获得此异常:输入不是有效的 Base-64 字符串,因为它包含非 Base-64 字符、两个以上的填充字符或填充字符中的非法字符。 (2认同)

A12*_*123 8

response.Content.ReadAsAsync<byte[]>().Result //Put this code in your client.

我想讲清楚ReadAsAsync<byte[]>(),并ReadAsByteArrayAsync()采取同样.

ReadAsByteArrayAsync()将所有内容都转换为字节数组.它没有得到byte[]来自response.Content

  • 或:response.Content.ReadAsByteArrayAsync().结果 (3认同)

ber*_*oft 6

用这个改变你的控制器,你会得到与你发送的相同的尺寸

[HttpPost]
[Route("SomeRoute")]
public FileStreamResult MyMethod([FromBody] string ID)
{
  byte[] mybytearray = db.getmybytearray(ID);
  return File(new MemoryStream(mybytearray), "application/octet-stream");
}
Run Code Online (Sandbox Code Playgroud)

这是一个问题https://github.com/aspnet/Mvc/issues/7926


小智 5

代替这个

mybytearray = response.Content.ReadAsByteArrayAsync().Result;//Here is the problem
Run Code Online (Sandbox Code Playgroud)

用这个

string result=null;
result = response.Content.ReadAsStringAsync().Result.Replace("\"", string.Empty);
 mybytearray=Convert.FromBase64String(result);
Run Code Online (Sandbox Code Playgroud)

响应返回的字节数组为base64encoded。