C# 使用JSON.NET对复杂对象进行序列化和反序列化
我在使用JSON.NET转换器和ASP.NET WebApi时遇到了一个问题。下面是该场景的表示 属性类可以是Parent类型或Measurement类型,并具有所述属性的序列化性质C# 使用JSON.NET对复杂对象进行序列化和反序列化,c#,asp.net,serialization,json.net,deserialization,C#,Asp.net,Serialization,Json.net,Deserialization,我在使用JSON.NET转换器和ASP.NET WebApi时遇到了一个问题。下面是该场景的表示 属性类可以是Parent类型或Measurement类型,并具有所述属性的序列化性质 [DataContract] [JsonConverter(typeof(AttributeConverter))] public abstract class Attribute { [DataMember] public string Id { get; set; } [DataMem
[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; }
}
根据我们的要求,我需要一个标识符来指定属性的类型,该属性与“$type”提供的属性相同。我们已经编写了一个自定义转换器,它将在序列化期间引入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;
}
public override void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
writer.WriteStartObject();
writer.WritePropertyName(“AttributeKind”);
AttributeKind type=(AttributeKind)System.Enum.Parse(typeof(AttributeKind),value.GetType().Name);
writer.WriteValue(类型);
var props=value.GetType().GetProperties();
foreach(道具中的var propertyInfo)
{
var tempVal=propertyInfo.GetValue(值,null);
如果(tempVal==null)继续;
writer.WritePropertyName(propertyInfo.Name);
serializer.Serialize(writer,tempVal);
}
writer.WriteEndObject();
}
公共重写对象ReadJson(JsonReader阅读器、System.Type对象类型、对象existingValue、JsonSerializer序列化程序)
{
JObject JObject=序列化程序。反序列化(读取器);
JProperty JProperty=jObject.Properties().FirstOrDefault(p=>p.Name==“AttributeKind”);
如果(jProperty==null)
返回null;
JValue value=jProperty.value作为JValue;
AttributeKind AttributeKind=(AttributeKind)System.Enum.Parse(typeof(AttributeKind),value.value.ToString());
属性=null;
开关(属性绑定)
{
案例属性kind.ParentAttribute:
属性=新的ParentAttribute();
打破
案例属性kind.MeasurementAttribute:
属性=新的度量属性();
打破
}
var props=attribute.GetType().GetProperties();
foreach(道具中的var propertyInfo)
{
jProperty=jObject.Properties().FirstOrDefault(p=>p.Name==propertyInfo.Name);
如果(jProperty!=null)
{
JValue JValue=jProperty.Value作为JValue;
if(jValue!=null)
{
对象数据值=null;
if(jValue.Type==JTokenType.Integer)
dataValue=System.Convert.ToInt32(jValue.Value);
其他的
dataValue=jValue.Value;
propertyInfo.SetValue(属性,数据值,null);
}
}
}
返回属性;
}
以下是在反序列化响应中观察到的问题:
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;
}