如何使用jsonfx过滤/转换要序列化的对象属性?

时间:2015-09-25 13:08:21

标签: c# .net json serialization jsonfx

我使用JsonFX将实例序列化为json,我需要忽略一些属性并预处理其他属性。我怎么做 ?该文件对此并不十分清楚。

我的课看起来有点像这样:

public class Primitive{
    public string type;
    public float[] vertices;
    public int[] indices;
    public int[] edgeIndices;
    public Scene scene;

输出json时,我需要忽略scene属性(整个3d场景)并预处理verticesindices,{{1使用一些压缩方案。

显然,我在接收json时需要对称操作。

但是怎么样?

1 个答案:

答案 0 :(得分:2)

您可以将[JsonIgnore]JsonResolverStrategy一起使用:

public class Scene
{
    public string Name { get; set; } // Or whatever
}

public class Primitive
{
    public string type;
    public float[] vertices;
    public int[] indices;
    public int[] edgeIndices;
    [JsonFx.Json.JsonIgnore]
    public Scene scene;
}

public class TestClass
{
    public static void Test()
    {
        var primitive = new Primitive
        {
            type = "some type",
            vertices = new[] { 1.0f, 2.0f },
            indices = new[] { 1, 2 },
            edgeIndices = new[] { 0, 1 },
            scene = new Scene { Name = "Should Not Be Serialized" }
        };

        var writer = new JsonWriter(new DataWriterSettings(new JsonResolverStrategy()));

        var json = writer.Write(primitive);

        Debug.WriteLine(json);  // Prints {"type":"some type","vertices":[1,2],"indices":[1,2],"edgeIndices":[0,1]}
        Debug.Assert(!json.Contains("Should Not Be Serialized")); // No assert
    }
}

或者,您可以将data contract attributesDataContractResolverStrategy一起使用:

public class Scene
{
    public string Name { get; set; } // Or whatever
}

[DataContract]
public class Primitive
{
    [DataMember]
    public string type;
    [DataMember]
    public float[] vertices;
    [DataMember]
    public int[] indices;
    [DataMember]
    public int[] edgeIndices;
    [IgnoreDataMember]
    public Scene scene;
}

public class TestClass
{
    public static void Test()
    {
        var primitive = new Primitive
        {
            type = "some type",
            vertices = new[] { 1.0f, 2.0f },
            indices = new[] { 1, 2 },
            edgeIndices = new[] { 0, 1 },
            scene = new Scene { Name = "Should Not Be Serialized" }
        };

        var writer = new JsonWriter(new DataWriterSettings(new DataContractResolverStrategy()));

        var json = writer.Write(primitive);

        Debug.WriteLine(json);
        Debug.Assert(!json.Contains("Should Not Be Serialized")); // No assert
    }
}

(但请注意,DataContractResolverStrategy在.Net 3.5。中已被破坏,因此,如果您仍然使用旧版本,则无法使用它。)

<强>更新

转换&#34;转换&#34;序列化期间的属性是使用代理属性,例如:

public class Primitive
{
    public string type;

    public float[] vertices;

    [JsonFx.Json.JsonIgnore]
    public int[] indices;

    [JsonFx.Json.JsonName("indices")]
    public string compressedIndices
    {
        get
        {
            return indices.Base64Compress();
        }
        set
        {
            indices = CompressionExtensions.Base64DecompressIntArray(value);
        }
    }

    public int[] edgeIndices;

    [JsonFx.Json.JsonIgnore]
    public Scene scene;
}

public static class CompressionExtensions
{
    public static string Base64Compress(this IEnumerable<int> values)
    {
        if (values == null)
            return null;
        using (var stream = new MemoryStream())
        {
            using (var compressor = new DeflateStream(stream, CompressionMode.Compress, true))
            {
                var _buffer = new byte[4];
                foreach (var value in values)
                {
                    _buffer[0] = (byte)value;
                    _buffer[1] = (byte)(value >> 8);
                    _buffer[2] = (byte)(value >> 16);
                    _buffer[3] = (byte)(value >> 24);
                    compressor.Write(_buffer, 0, 4);
                }
            }
            return Convert.ToBase64String(stream.GetBuffer(), 0, checked((int)stream.Length)); // Throw an exception on overflow.
        }
    }

    public static int[] Base64DecompressIntArray(string base64)
    {
        if (base64 == null)
            return null;
        var list = new List<int>();
        var m_buffer = new byte[4];
        using (var stream = new MemoryStream(Convert.FromBase64String(base64)))
        {
            using (var compressor = new DeflateStream(stream, CompressionMode.Decompress))
            {
                while (compressor.Read(m_buffer, 0, 4) == 4)
                {
                    list.Add((int)(m_buffer[0] | m_buffer[1] << 8 | m_buffer[2] << 16 | m_buffer[3] << 24));
                }
            }
        }
        return list.ToArray();
    }
}

然后像这样写和读:

        var primitive = new Primitive
        {
            type = "some type",
            vertices = new[] { 1.0f, 2.0f },
            indices = Enumerable.Range(0, 10000).Select(i => 0).ToArray(),
            edgeIndices = new[] { 0, 1 },
            scene = new Scene { Name = "Should Not Be Serialized" }
        };

        var writer = new JsonWriter(new DataWriterSettings(new JsonResolverStrategy()));

        var json = writer.Write(primitive);

        var reader = new JsonReader(new DataReaderSettings(new JsonResolverStrategy()));
        var primitiveBack = reader.Read<Primitive>(json);

        Debug.Assert(primitiveBack.indices.SequenceEqual(primitive.indices));