28

JSON.net を使用して、C# と JavaScript の間でいくつかのオブジェクトをシリアル化します。JSON データは、.NET とブラウザー アプリケーションの間で WebSocket を介して転送されます。

データ構造にはいくつかのフィールドがありますがbyte[]、これらのフィールドをArrayJavaScript でも使用したいと考えています。

C# をbase64 文字列の代わりにbyte[]単純な JSON 配列にシリアル化するにはどうすればよいですか?[ 0 , 1 , 254, 255 ]

4

3 に答える 3

65

JSON.NET はBinaryConverter、バイト配列を読み書きするために を選択しています。ソースでは、バイト配列を使用WriteValueしてクラスで操作を使用しているため、Base-64 として書き込まれていることがわかります。JsonWriter

これを変更するには、期待する形式で配列を読み書きする独自のコンバーターを作成できます。

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[]);
    }
}

JsonConverterAttributeメンバーに を適用して、これを使用します。

[JsonConverter(typeof(ByteArrayConverter))]
public byte[] Data { get; set; }
于 2013-03-05T15:58:47.967 に答える
16

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

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

これには、JSONライブラリの特別な処理や、カスタムシリアル化などは必要ありません。

編集:これは、異なるタイプを処理するためにデータオブジェクトをカスタマイズする必要があることを意味します。多分:

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

したがって、おそらくそれは最も単純ではありません-シリアル化する必要があるものの量によって異なります

于 2013-03-05T15:01:22.303 に答える