2013-07-24 50 views
2

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

JavaScript示例:(AJAX.Post是我写的一个图书馆,myUint8Array正确序列化)

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

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

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

} 

在这个例子中myByteArray总是空值。我尝试了几种基于转换为字符串,然后返回字节[]的不同方法,但是我无法获得正确的值。如果我能以某种方式将代码直接实现到.NET的JSON反序列化器中,以便上面的代码完全按照原样工作,这将是非常受欢迎的,因为我有一些其他项目,如果可以直接在字符串之间传递字节数组,服务器端和客户端应用程序。

回答

0

更改您的控制器操作以接受int[]而不是byte[],然后转换为字节数组。帖子值仍然可以是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对客户端的字节进行编码并将其作为字符串传递。

可能有其他选择,如过滤器或属性或类似的东西,但这是我知道的最简单的方法。

+0

int []仍然没有选择它,它仍然为空。我认为问题在于Uint8Array不会序列化为实际的JSON数组,它会在其他几个属性中序列化为具有属性{0:168,1:49,...}的对象。 – user1084447

+0

这很有趣 - 没有意识到将一个'Uint8Array'序列化为一个常规对象而不是一个直线阵列。看起来好像你是否可以通过调用'myUnit8Array.subarray()'将'Uint8Array'转换成一个常规数组,这应该给你一个字节,然后你可以将这些字节写入'int []'参数。可能值得将它与你的base-64解决方案进行比较,看看哪一个可以提供更小的占位面积。 –

+0

myUnit8Array.subarray()仍然会产生相同的奇怪对象{0:168,1:49,...} – blaster

2

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

的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); 
} 
3

我面临着同样的问题,很多[R & D.之后,我来到了一些结论。

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

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

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

方法3: 第三种方法是将字节数组转换为base64编码的字符串并发送它。虽然这增加了33%的文件大小,但这种方法远胜于上述两种。我可以轻松地发送15 MB文件,浏览器的内存消耗是80MB,发送这3个文件时消耗会变少。

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

请让我知道如果我错了。

0

必须使用Jason.stringify序列化的IT和设置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 
    } 
0

大厦user1084447的溶液(序列化和反序列化到Base64字符串),此作品不错序列化:

var serialized = fromByteArray(myUint8Array); 

fromeByteArray功能来自this github project。我从this documentation on mdn了解到base64-js。