使用JSON.NET对复杂对象进行序列化和反序列化

时间:2014-05-27 13:19:31

标签: c# asp.net serialization json.net deserialization

我在使用ASP.NET WebApi的JSON.NET转换器时遇到了问题。以下是场景的表示

属性类可以是Parent或Measurement类型,具有所提及属性的序列化特性。

[DataContract]
[JsonConverter(typeof(AttributeConverter))]    
public abstract class Attribute
{

    [DataMember] public string Id { get; set; }
    [DataMember] public string DisplayLabel { get; set; }
}

[DataContract]
public class Parent : Attribute
{
    [DataMember] public List<Attribute> Attributes { get; set; }
}

[DataContract]
public class Measurement : Attribute
{
    [DataMember] public Bound Bounds { get; set; }
    [DataMember] public int measurementValue { get; set; }
}

我不想要默认&#34; $ type&#34;在序列化期间为Json.NET处理类型而注入的属性,因此在WebApiConfig.cs中设置了以下属性

config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.None;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling =` Newtonsoft.Json.PreserveReferencesHandling.None;

根据我们的要求,我需要一个标识符来指定属性的类型,这与&#34; $ type&#34;相同。提供。我们编写了一个自定义转换器,它将在序列化期间引入AttributeKind信息,并在使用我的转换器的ReadJson()进行反序列化时恢复。代码段如下所示

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
   writer.WriteStartObject();
   writer.WritePropertyName("AttributeKind");

   AttributeKind type = (AttributeKind)System.Enum.Parse(typeof(AttributeKind), value.GetType().Name);
   writer.WriteValue(type);

   var props = value.GetType().GetProperties();
   foreach (var propertyInfo in props)
   {
       var tempVal = propertyInfo.GetValue(value, null);
       if (tempVal == null) continue;

       writer.WritePropertyName(propertyInfo.Name);
       serializer.Serialize(writer, tempVal);
    }
    writer.WriteEndObject();
}

public override object ReadJson(JsonReader reader, System.Type objectType, object existingValue, JsonSerializer serializer)
{
    JObject jObject = serializer.Deserialize<JObject>(reader);

    JProperty jProperty = jObject.Properties().FirstOrDefault(p => p.Name == "AttributeKind");

    if (jProperty == null)
        return null;

    JValue value = jProperty.Value as JValue;

    AttributeKind attributeKind = (AttributeKind)System.Enum.Parse(typeof(AttributeKind), value.Value.ToString());

    Attribute attribute = null;
    switch (attributeKind)
    {
        case AttributeKind.ParentAttribute:
            attribute = new ParentAttribute();
            break;

        case AttributeKind.MeasurementAttribute:
            attribute = new MeasurementAttribute();
            break;
    }

    var props = attribute.GetType().GetProperties();
    foreach (var propertyInfo in props)
    {
        jProperty = jObject.Properties().FirstOrDefault(p => p.Name == propertyInfo.Name);
        if (jProperty != null)
        {
            JValue jValue = jProperty.Value as JValue;

            if (jValue != null)
            {
                object dataValue = null;
                if (jValue.Type == JTokenType.Integer)
                    dataValue = System.Convert.ToInt32(jValue.Value);
                else
                    dataValue = jValue.Value;

                propertyInfo.SetValue(attribute, dataValue, null);
            }
        }
    }
    return attribute;
}

以下是在反序列化响应中观察到的问题:

  1. ParentType属性的空属性列表,其中序列化输入包含元素。
  2. 尚未填充Bounds属性并返回null。
  3. 我无法前进,因为我似乎没有完全理解JsonConverters如何被截获以及如果存在链接转换器(例如,2个转换器...类和另一个复杂属性)

    非常感谢任何帮助?感谢

0 个答案:

没有答案