【问题标题】:How to Get byte array properly from an Web Api Method in C#?如何从 C# 中的 Web Api 方法正确获取字节数组?
【发布时间】:2014-07-16 01:22:16
【问题描述】:

我有以下控制器方法:

[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字节)并且值也被弄乱了。

【问题讨论】:

    标签: c# asp.net-web-api


    【解决方案1】:

    这是我的方法,它对我有用

    WEP API 方法

                [HttpGet]
                [Route("pdfReport")]
                public byte[] ReportMRWiseCurrentStatus()
                {
        
                    byte[] resultsarray = _materialRequestReportService.ReportMRWiseCurrentStatus();
                    return resultsarray;
                }
    

    客户

    using (var client = new HttpClient())
                {
                    var response = client.GetAsync(webApiUrl);
                    if (response.Result.IsSuccessStatusCode)
                    {
    
                        var result = response.Result.Content.ReadAsStringAsync().Result.Replace("\"", string.Empty);
    
                        var bytearray=Convert.FromBase64String(result);
                        System.IO.File.WriteAllBytes(@"C:\DB\newpdfAmila.pdf", bytearray);
                    }
    
                 }
    

    【讨论】:

      【解决方案2】:

      用这个改变你的控制器,你会得到和你发送的一样的尺寸

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

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

      【讨论】:

        【解决方案3】:

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

        我想明确指出,ReadAsAsync<byte[]>()ReadAsByteArrayAsync() 行为相同。

        ReadAsByteArrayAsync() 将所有内容转换为 Base64 字节数组。它没有从 response.Content 获得非 Base64 byte[],但 ReadAsAsync<byte[]>() 可以

        【讨论】:

        • 或:response.Content.ReadAsByteArrayAsync().Result
        【解决方案4】:

        从 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
        

        【讨论】:

          【解决方案5】:

          不是这个

          mybytearray = response.Content.ReadAsByteArrayAsync().Result;//Here is the problem
          

          使用这个

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

          响应将字节数组作为 base64 编码返回。

          【讨论】:

          • 为什么.ReadAsStringAsync()的结果会在" "中包裹想要的字符串?
          【解决方案6】:

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

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

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

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

          【讨论】:

          • 出现此异常:输入不是有效的 Base-64 字符串,因为它包含非 base 64 字符、两个以上的填充字符或填充字符中的非法字符。
          • 非常感谢。我只需要从一开始就删除“\”,它就像一个魅力!
          【解决方案7】:

          实际上,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;
          }
          

          使用某些属性或其他东西也许可以做同样的事情,但我不知道如何。

          【讨论】:

            猜你喜欢
            • 2015-04-09
            • 1970-01-01
            • 2021-12-06
            • 2018-12-29
            • 1970-01-01
            • 1970-01-01
            • 2015-03-02
            • 1970-01-01
            相关资源
            最近更新 更多