【问题标题】:Returning byte array from server is different when received by the client客户端收到时从服务器返回的字节数组不同
【发布时间】:2020-07-03 22:07:17
【问题描述】:

我有一个 REST API 试图从我的 web api 调用(获取)一个字节数组。 这是我的客户代码:

Uri uri = new Uri(URL);
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/Binary"));
HttpResponseMessage response = await httpClient.GetAsync(uri + route + "?" + COMPANY_REF + "=" + ApplicationObject.CompanyRef);
response.EnsureSuccessStatusCode();
var result = response.Content.ReadAsByteArrayAsync().Result

这是我的服务器 API:

[HttpGet]
public byte[] Get(Guid companyRef)
{
    Mapper.CreateMap<Services.Group,Models.Group>();
    var test = Mapper.Map<List<Models.Group>>(groupRepository.Get(companyRef));
    var t = Compression.Serialize(test);
    return t;
}


public static byte[] Serialize(this Object obj)
{
    if (obj == null)
    {
        return null;
    }

    using (var memoryStream = new MemoryStream())
    {
        var binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(memoryStream, obj);
        var compressed = Compression.Zip(memoryStream.ToArray());

        return compressed;
    }
}

服务器返回的字节数组为:

客户端收到的字节数组为:

如您所见,这是错误的大小和值。

我假设这取决于当前设置的媒体标头:

httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/Binary"));

使用 Fiddler 似乎认为它期待 Json。所以我把它改成了 '应用程序/json'

那没有用。

我也使用了 base64Binary,但也没有用。

我还能尝试什么?

附加: 直接在浏览器中输入 api 的结果:

<base64Binary xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
H4sIAAAAAAAEAKWS32vUQBDHN3u5TXJRUSr1B4pBX49g/4CDlhb64K9Dq304jjWXTK/rbXePbCKc4N8qCIIgCILvOnO92KDNkxP2m2SYz8zszjKPMfYLjd5kVzjK7jHMxrasMj1M3kDplDWjnfQxPcNkv9ZVXcLIQF2VFDGuZ1rlT2B1ZBdgRqbW2qd0H1+tXAVn6b7VGvIKk7j0EAyUKk+fKle93ZlM/hRKn9kCNAaUtl4Ok/9tYDrtYQdCKmzA9aVTHyCU788z+YzdvrzuZEq7D8OI4BBXhCugH+ZtPP725SiBkU/SJxEkAck6DeWJBiQxSp/iOvKsK6+/XsKJ/zw7g/gAXF6qJR1gz/Pizake1qqgov5PnF7bSRW4zLiccZlzWXAJXJ5wOefylEvF5TsuF+zCwiDgG2N/mbiKEh/ZIlu55NiWC3GNvOfFPNoo7cT7gR1QF//g11F6e1qLGy1MNNj3LmwLZfDaZM6puYFC3GzRQUN/66K3KeLFEoy41eLChvvaxd2hWY/BFMrMxd0WGjXoly70HqF7M5wmdnu/hQ4a9HMX+oAiDqwBkbS4uOE+dXEPKcLg9RCPaEbFxR2JfwNB64eo1AMAAA==
</base64Binary>

更多信息:

如果改变这个:

 var result = response.Content.ReadAsByteArrayAsync().Result;
    byte[] resultFromServer = Encoding.ASCII.GetBytes("H4sIAAAAAAAEAKWS32vUQBDHN3u5TXJRUSr1B4pBX49g/4CDlhb64K9Dq304jjWXTK/rbXePbCKc4N8qCIIgCILvOnO92KDNkxP2m2SYz8zszjKPMfYLjd5kVzjK7jHMxrasMj1M3kDplDWjnfQxPcNkv9ZVXcLIQF2VFDGuZ1rlT2B1ZBdgRqbW2qd0H1+tXAVn6b7VGvIKk7j0EAyUKk+fKle93ZlM/hRKn9kCNAaUtl4Ok/9tYDrtYQdCKmzA9aVTHyCU788z+YzdvrzuZEq7D8OI4BBXhCugH+ZtPP725SiBkU/SJxEkAck6DeWJBiQxSp/iOvKsK6+/XsKJ/zw7g/gAXF6qJR1gz/Pizake1qqgov5PnF7bSRW4zLiccZlzWXAJXJ5wOefylEvF5TsuF+zCwiDgG2N/mbiKEh/ZIlu55NiWC3GNvOfFPNoo7cT7gR1QF//g11F6e1qLGy1MNNj3LmwLZfDaZM6puYFC3GzRQUN/66K3KeLFEoy41eLChvvaxd2hWY/BFMrMxd0WGjXoly70HqF7M5wmdnu/hQ4a9HMX+oAiDqwBkbS4uOE+dXEPKcLg9RCPaEbFxR2JfwNB64eo1AMAAA==");
    byte[] actualBytes = Convert.FromBase64String(Encoding.ASCII.GetString(resultFromServer));

到这里:

var result = response.Content.ReadAsStringAsync().Result;
byte[] resultFromServer = Encoding.ASCII.GetBytes(result);
byte[] actualBytes = Convert.FromBase64String(Encoding.ASCII.GetString(resultFromServer));

我得到错误:

输入不是有效的 Base-64 字符串,因为它包含非 base 64 字符、两个以上的填充字符或填充字符中的非法字符。

这是结果的值

"H4sIAAAAAAAEAKWS32vUQBDHN3u5TXJRUSr1B4pBX49g/4CDlhb64K9Dq304jjWXTK/rbXePb CKc4N8qCIIgCILvOnO92KDNkxP2m2SYz8zszjKPMfYLjd5kVzjK7jHMxrasMj1M3kDplDWjnfQ xPcNkv9ZVXcLIQF2VFDGuZ1rlT2B1ZBdgRqbW2qd0H1+tXAVn6b7VGvIKk7j0EAyUKk +fKle93ZlM/hRKn9kCNAaUtl4Ok/9tYDrtYQdCKmzA9aVTHyCU788z +YzdvrzuZEq7D8OI4BBXhCugH +ZtPP725SiBkU/SJxEkAck6DeWJBiQxSp/iOvKsK6+/XsKJ/zw7g/gAXF6qJR1gz/Pizake1qq gov5PnF7bSRW4zLiccZlzWXAJXJ5wOefylEvF5TsuF +zCwiDgG2N/mbiKEh/ZIlu55NiWC3GNvOfFPNoo7cT7gR1QF//g11F6e1qLGy1MNNj3LmwLZfD aZM6puYFC3GzRQUN/66K3KeLFEoy41eLChvvaxd2hWY/BFMrMxd0WGjXoly70HqF7M5wmdnu/h Q4a9HMX+oAiDqwBkbS4uOE+dXEPKcLg9RCPaEbFxR2JfwNB64eo1AMAAA=="

来自 Debug.Write:

"H4sIAAAAAAAEAKWS32vUQBDHN3u5TXJRUSr1B4pBX49g/4CDlhb64K9Dq304jjWXTK/rbXePbCKc4N8qCIIgCILvOnO92KDNkxP2m2SYz8zszjKPMfYLjd5kVzjK7jHMxrasMj1M3kDplDWjnfQxPcNkv9ZVXcLIQF2VFDGuZ1rlT2B1ZBdgRqbW2qd0H1+tXAVn6b7VGvIKk7j0EAyUKk+fKle93ZlM/hRKn9kCNAaUtl4Ok/9tYDrtYQdCKmzA9aVTHyCU788z+YzdvrzuZEq7D8OI4BBXhCugH+ZtPP725SiBkU/SJxEkAck6DeWJBiQxSp/iOvKsK6+/XsKJ/zw7g/gAXF6qJR1gz/Pizake1qqgov5PnF7bSRW4zLiccZlzWXAJXJ5wOefylEvF5TsuF+zCwiDgG2N/mbiKEh/ZIlu55NiWC3GNvOfFPNoo7cT7gR1QF//g11F6e1qLGy1MNNj3LmwLZfDaZM6puYFC3GzRQUN/66K3KeLFEoy41eLChvvaxd2hWY/BFMrMxd0WGjXoly70HqF7M5wmdnu/hQ4a9HMX+oAiDqwBkbS4uOE +dXEPKcLg9RCPaEbFxR2JfwNB64eo1AMAAA=="

为了让这最终发挥作用,我必须这样做:

byte[] actualBytes = Convert.FromBase64String(result2.Replace("\"",""));

谢谢

【问题讨论】:

  • 您是否考虑过将生成的字节数组转换为 uft-8 字符串或只是将内容作为字符串读取?也许我们那里隐藏了一些信息
  • @RX_DID_RX 嗨,谢谢你可怜我。我已经编辑了我的问题,以显示如果我直接在浏览器中输入 api 会发生什么。我当然会按照您的建议转换为 utf-8 并报告。谢谢
  • @RX_DID_RX 我从 utf-8 得到的所有信息都与附加信息相同 :(

标签: c# rest serialization bytearray asp.net-web-api


【解决方案1】:

由于您以字符串形式获取响应,因此只需对该 Base64 字符串进行解码。

var result = response.Content.ReadAsStringAsync().Result;
byte[] actualBytes = Convert.FromBase64String(result);

【讨论】:

  • 嗨,我得到了一个更奇怪的结果。我将编辑我的问题来解释
  • 但我可以成功获取实际字节,并且可以看到它与您从 Web 服务器发送的 byte[] 相同。在您编辑您的帖子后,我复制了 base64 内容并将其分配给 result 并且仍然成功。
  • 好的,现在你已经得到了字符串的结果,那么你只能解码它。
  • 这就是我所说的怪异。复制并粘贴该字符串,它可以工作,但不能直接从结果变量中读取。在复制和粘贴的行为中必须有一些转换。谷歌搜索了一段时间了。为什么是我?
  • 那么结果变量里面一定有一些额外的字符。你能用 Debug.Write 转储它吗?
【解决方案2】:

经过一些研究,我发现 asp net core 团队不想解决这个问题 (https://github.com/aspnet/Mvc/issues/7926),要解决您的问题,您必须返回“FileStreamResult”。

用这个改变你的控制器

[HttpGet]
public FileStreamResult Get(Guid companyRef)
{
    Mapper.CreateMap<Services.Group, Models.Group>();
    var test = Mapper.Map<List<Models.Group>>(groupRepository.Get(companyRef));
    var t = Compression.Serialize(test);
    return File(new MemoryStream(t), "application/octet-stream");
}

【讨论】:

    猜你喜欢
    • 2020-06-04
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多