我有一个对象:
[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);
}
}
答案 0 :(得分:1)
这应该可以胜任你的工作。我刚写了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您想要使用自定义转换器。所以无论你想在哪里使用它,你都必须通过属性调用。
我也在做类似的事情,我必须手动调用转换器。
/// <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; }
答案 1 :(得分:1)
如果您正在寻找特定的输出,我认为您不会找到比您拥有的更清洁的解决方案。如果真正的目标是以紧凑的方式序列化JSON,请查看BSON或ProtoBuf等标准