对象到数组的序列化



我有一个对象:

[JsonConverter(typeof(MessageConverter))]
public class Message
{
    [JsonProperty(Order = 1)]
    public long Id { get; set; }
    [JsonProperty(Order = 2)]
    public string Msg { get; set; }
    [JsonProperty(Order = 3)]
    public int Timestamp { get; set; }
}

我想将其串行化为以下形式的JSON数组:

[long, string, int]

这个类将嵌套在层次结构中,因此自动转换将是首选。

我目前正在使用以下代码,但这似乎包含了大量的重复。

我想知道是否有一个属性/更紧凑的解决方案可以让JSON.NET在没有转换器的情况下使用所提供的属性来提供相同的功能。

public class MessageConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Message);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var arr = serializer.Deserialize<JToken>(reader) as JArray;
        if (arr == null || arr.Count != 3)
            throw new JsonSerializationException("Expected array of length 3");
        return new Message
        {
            Id = (long)arr[0],
            Msg = (string)arr[1],
            Timestamp = (int)arr[2]
        };
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var msg = value as Message;
        var obj = new object[] { msg.Id, msg.Msg, msg.Timestamp };
        serializer.Serialize(writer, obj);
    }
}

如果您正在寻找特定的输出,我认为您不会找到比现有更干净的解决方案。如果您的real目标是以紧凑的方式序列化JSON,请参阅BSON或ProtoBuf

等标准

这应该能胜任你的工作。我只是为WRITE写的,即输出。

namespace Test
{
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections;
    using System.Reflection;
    /// <summary>
    /// Defines the custom JSON Converter of collection type that serialize collection to an array of ID for Ember.
    /// </summary>
    public class CustomConverter : JsonConverter
    {
        /// <summary>
        /// Define the property name that is define in the collection type.
        /// </summary>
        private readonly string IDKEY = "Id";
        private readonly string MSGKEY = "Msg";
        private readonly string TIMEKEY = "Timestamp";
        /// <summary>
        /// It is write only convertor and it cannot be read back.
        /// </summary>
        public override bool CanRead
        {
            get { return false; }
        }
        /// <summary>
        /// Validate that this conversion can be applied on IEnumerable type only.
        /// </summary>
        /// <param name="objectType">type of object</param>
        /// <returns>Validated value in boolean</returns>
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Message);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
            JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// Write JSON data from IEnumerable to Array.
        /// </summary>
        /// <param name="writer">JSON Writer</param>
        /// <param name="value">Value of an object</param>
        /// <param name="serializer">JSON Serializer object</param>
        public override void WriteJson(JsonWriter writer, object item, JsonSerializer serializer)
        {
            JArray array = new JArray();
            PropertyInfo prop = item.GetType().GetProperty(IDKEY);
            if (prop != null && prop.CanRead)
            {
                array.Add(JToken.FromObject(prop.GetValue(item, null)));
            }
            prop = item.GetType().GetProperty(MSGKEY);
            if (prop != null && prop.CanRead)
            {
                array.Add(JToken.FromObject(prop.GetValue(item, null)));
            }
            prop = item.GetType().GetProperty(TIMEKEY);
            if (prop != null && prop.CanRead)
            {
                array.Add(JToken.FromObject(prop.GetValue(item, null)));
            }

            array.WriteTo(writer);
        }
    }
}

您正在告诉JSON.NET您希望使用自定义转换器。因此,无论您想在哪里使用它,都必须调用through属性。

我也在做类似的事情,我必须手动调用转换器。

  /// <summary>
        /// Gets or sets collection of documents.
        /// </summary>
        [JsonConverter(typeof(IDWriteListConverter))]
        public ICollection<Document> Documents { get; set; }
        /// <summary>
        /// Gets or sets collection of comments.
        /// </summary>
        [JsonConverter(typeof(IDWriteListConverter))]
        public ICollection<Comment> Comments { get; set; }
        /// <summary>
        /// Gets or sets the collection of transactions.
        /// </summary>
        [JsonConverter(typeof(IDWriteListConverter))]
        public virtual ICollection<Transaction> Transactions { get; set; }

相关内容

  • 没有找到相关文章

最新更新