7

我在客户端 Web 应用程序上使用 js-scrypt ( https://github.com/tonyg/js-scrypt ) 对密码进行散列和加盐,然后再将它们发布到我的服务器端 .NET MVC 应用程序进行散列和再次腌制。这个 JavaScript 库将字节数组实现为 JavaScript Uint8Arrays。如何让我的 MVC 控制器将我的 JSON Uint8Array 反序列化为字节 []?

JavaScript 示例:(AJAX.Post 是我编写的库,myUint8Array 可以正确序列化)

AJAX.Post('www.example.com/SendByteArray', { myByteArray: myUint8Array }, Callback);

C# 示例:(在我的默认控制器中)

[HttpPost]
public async Task<JsonResult> SendByteArray(byte[] myByteArray) {

}

在此示例中,myByteArray 始终为空。我已经尝试了几种不同的方法,基于转换为字符串然后返回到 byte[] 但我无法获得正确的值。如果我能以某种方式直接将代码实现到 .NET 的 JSON 反序列化器中,以便上面的代码完全按原样工作,那将是非常可取的,因为我还有一些其他项目,如果我可以直接在它们之间传递字节数组,我可以做一些很酷的事情服务器端和客户端应用程序。

4

7 回答 7

6

目前,我可以开始工作的唯一方法是对 Uint8Array 进行 base64 编码,将其捕获为 C# 中的字符串,然后将该字符串转换为字节 []。

JavaScript:

AJAX.Post('www.example.com/SendByteArray', { strByteArray: btoa(String.fromCharCode.apply(null, myUint8Array)) }, Callback);

C#:

[HttpPost]
public async Task<JsonResult> SendByteArray(string strByteArray) {
    byte[] myByteArray = Convert.FromBase64String(strByteArray);
}
于 2013-07-25T14:47:21.753 回答
4

经过大量的研发,我面临同样的问题。我得出的结论很少。

方法 1:C# 无法反序列化 javascript 类型数组(UInt8Array、UInt16Array 等)。应该将数据从类型化数组复制到普通的 java 脚本数组中,并且应该发送该数据。在接收端(C# 端点方法),参数应该是整数数组而不是字节数组。如果放置了字节数组,则在端点接收到的数据为空。接收到的整数数组应转换为字节数组以进行文件恢复。

方法 2:发送类型化数组数据而不是将 javascript 类型化数组数据复制到普通数组中的另一种选择是按原样发送类型化数组数据,并且在接收端(C# 端点方法),方法参数应该是对象。该对象应使用一些 linq 进行迭代,并应转换为字节数组以进行文件恢复。

据我说,上面发现的两种方法都非常慢。当我发送 3 个大小为 5MB 的文件时,我的浏览器(IE 10 浏览器)内存消耗在通过 Ajax 请求发送数据时呈指数增长。我仍然无法弄清楚这个问题。如果有人能够使用 Ajax 发送字节数组,请告诉我。

方法3:第三种方法是将字节数组转换为base64编码的字符串并发送。尽管这将文件大小增加了 33%,但这种方法比上述两种方法要好得多。我能够轻松发送 15 MB 文件,并且在发送这 3 个文件时浏览器的内存消耗约为 80MB,并且一旦发送文件,消耗就会减少。

重要提示:请在读取文件内容后释放变量的内存。IE中的垃圾收集不是那么好。使用 fileReader 读取文件后,我遇到了很多内存消耗问题。当不再需要时,释放文件中所有未使用的变量和字节数组内容。

如果我错了,请告诉我。

于 2014-10-17T18:34:32.847 回答
2

我无法更改服务器端的,因此我需要将byte[]类型保留在服务器的端点上。为了解决这个问题,我最终将 my 转换Uint8Array为一个简单的字节数组,JSON 将其解析为数组而不是对象。

            const byteArray = [];
            Object.keys(contentUint8Array).forEach((key) =>{
                const byteForKey = contentUint8Array[key];
                byteArray.push(byteForKey);
            });

这样 .Net 端点就能够反序列化为一个Byte数组。

于 2018-04-11T11:51:29.797 回答
1

将您的控制器操作更改为接受int[]而不是byte[],然后转换为字节数组。post 值仍然可以是 JSON 数组。

[HttpPost]
public async Task<JsonResult> SendByteArray(int[] myByteArray) {

     byte[] theBytes = myByteArray.Select(i => (byte)i).ToArray();

     // Or any one of a dozen other ways of converting it

}

为了发布到字节数组,您必须对客户端上的字节进行 base-64 编码,并将其作为字符串传递。

可能有替代方法,例如过滤器或属性或类似的东西,但这是我所知道的最简单的方法。

于 2013-07-24T21:39:12.357 回答
1

我使用以下代码将大文件从 Angular 5 分块上传到 ASP Core Web API。在客户端 - 将 ArrayBuffer 转换为 Base64String:

private arrayBufferToBase64String(buffer: ArrayBuffer) {
  let binaryString = ''
  var bytes = new Uint8Array(buffer);
  for (var i = 0; i < bytes.byteLength; i++) {
    binaryString += String.fromCharCode(bytes[i]);
  }

  return window.btoa(binaryString);
}

发布字符串(这是 Angular 2+ 版本):

var data = {
  data: this.arrayBufferToBase64String(arrayBuffer)
}

this.httpClient.post(url, data)

在服务器上(C#):

var bytes = Convert.FromBase64String(part.Data);

part是一个模型类:

public class FilePartModel
{
    public string Data { get; set; }
}
于 2018-04-17T07:15:44.477 回答
0

您必须使用Jason.stringify 对其进行序列化并设置 ajax 的某些属性。这是我使用的示例并且它有效

            var list = [];

           //Fill list array

            var parameters = {};
            parameters = JSON.stringify({ "Your parameter": list });
            jQuery.ajax({
                url: '@Url.Action("Your Action")';,
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                dataType: "html",
                traditional: true,
                data: parameters,
                success: function (data, textStatus, jqXHR) {
                   //TODO: on success
                },
                error: function (data) {
                       //TODO: on fail
                }    
            });

    [HttpPost]
    public async Task<JsonResult> SendByteArray(IEnumerable<byte> myByteArray) {

    }

     OR Do this Way

    [HttpPost]
    public async Task<JsonResult> SendByteArray(int[] myByteArray) {
      convert to byte here
    }
于 2016-01-01T10:58:49.323 回答
0

基于 user1084447 的解决方案(序列化和反序列化为 base64 字符串),这对于序列化非常有效:

var serialized = fromByteArray(myUint8Array);

fromeByteArray函数来自这个github项目。我从mdn 上的文档中了解了 base64-js 。

于 2017-05-15T11:46:23.833 回答