2013-03-05 11 views
22

JSON.netを使用して、C#とJavaScriptの間のオブジェクトをシリアライズします。 JSONデータは.NETとブラウザアプリケーションの間でWebSocketを介して転送されます。バイト[]を単純なJSON配列としてシリアル化するにはどうすればいいですか?

データ構造には、byte[]フィールドがあります。このフィールドもJavaScriptでArrayとします。

C#byte[]をbase64文字列の代わりに[ 0 , 1 , 254, 255 ]のようなシンプルなJSON配列にシリアル化するにはどうすればよいですか?これは、JSONライブラリーの特別な処理、または任意のカスタム直列またはようなものを必要としない

var intArray = byteArray.Select(b => (int)b).ToArray(); 

:私は考えることができる

答えて

11

最も簡単な方法は次のように、整数配列にバイト配列を変換することですそれ。

EDIT:これは、異なる種類のデータオブジェクトをカスタマイズする必要があることを意味します。多分:

public class CustomFoo : Foo 
{ 
    // SomeBytesHere is a byte[] in the base class 
    public new int[] SomeBytesHere { get;set; } 
} 

だから多分それは最も単純ではない - あなたは

+0

私は 'int配列'のソリューションが大好きです。作業は偉大で簡単に実行できます。そのヒントのために多くのありがとうございます。 – Marcus

+0

ブラボー。バイトはintに収まり、int []はバイトの配列です。もう一方のJSONバインディングを使用するWCFでは、JSONシリアル化DTOをbyte []プロパティで使用し、カスタムフォーマッタやBase64デコード/ストリームの書き込みを行わずに安全に逆シリアル化できます。 シリアライズされたJSONのサイズはかなり壮大ですが、機能します! –

+0

これはバイト配列の8倍のメモリを使用しますが、必ずしも実行可能な解決策ではありません。 – FINDarkside

40

JSON.NETは、バイトの配列を読み書きするBinaryConverterを選択されたシリアル化する必要がどのくらいのものに依存します。 the sourceJsonWriterクラスのWriteValueオペレーションを使用して、バイトの配列がBase-64として書き込まれることがわかります。

これを変更するには、あなたが期待する形式の配列を読み取り、書き込み、独自のコンバータ書くことができます:あなたがメンバーにJsonConverterAttributeを適用することによって、これを使用することになり

public class ByteArrayConverter : JsonConverter 
{ 
    public override void WriteJson(
     JsonWriter writer, 
     object value, 
     JsonSerializer serializer) 
    { 
     if (value == null) 
     { 
      writer.WriteNull(); 
      return; 
     } 

     byte[] data = (byte[])value; 

     // Compose an array. 
     writer.WriteStartArray(); 

     for (var i = 0; i < data.Length; i++) 
     { 
      writer.WriteValue(data[i]); 
     } 

     writer.WriteEndArray(); 
    } 

    public override object ReadJson(
     JsonReader reader, 
     Type objectType, 
     object existingValue, 
     JsonSerializer serializer) 
    { 
     if (reader.TokenType == JsonToken.StartArray) 
     { 
      var byteList = new List<byte>(); 

      while (reader.Read()) 
      { 
       switch (reader.TokenType) 
       { 
        case JsonToken.Integer: 
         byteList.Add(Convert.ToByte(reader.Value)); 
         break; 
        case JsonToken.EndArray: 
         return byteList.ToArray(); 
        case JsonToken.Comment: 
         // skip 
         break; 
        default: 
         throw new Exception(
         string.Format(
          "Unexpected token when reading bytes: {0}", 
          reader.TokenType)); 
       } 
      } 

      throw new Exception("Unexpected end when reading bytes."); 
     } 
     else 
     { 
      throw new Exception(
       string.Format(
        "Unexpected token parsing binary. " 
        + "Expected StartArray, got {0}.", 
        reader.TokenType)); 
     } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(byte[]); 
    } 
} 

を:

[JsonConverter(typeof(ByteArrayConverter))] 
public byte[] Data { get; set; } 
+1

実際のByteArrayConverterクラスを提供するためのボーナスポイント!ただし、小さなエラーがあります。既にJsonWriterを使用しているので、カンマを手動で追加する必要はありません。この部分を削除するだけです。 if(i!= data.Length) { writer.WriteRaw( "、"); } そうでないと、配列は次のようになります。[12、、54、、32、、8] –

+0

これはうまく動作し、jsonインターフェイスの使用方法のようです。 –

関連する問題