我正在尝试序列化我的产品对象,但我的程序一直在崩溃。这可能是由于我的ProductPropertyValue和PropertyValue循环引用。但是你可以从我的JSON中看到,我的JSON中实际上没有循环引用,只有可能存在一个。
当然我在发布问题之前试图找到解决方案。我发现的大多数答案都包含了这些JsonSerializerSettings的一些变体:ReferenceLoopHandling
和PreserveReferencesHandling
。但无论我尝试设置什么设置,都没有效果。
我是否遗漏了一些明显的东西,或者我正在尝试做什么更好的解决方案?
JSON
{
"id": "skdlfkioajzze",
"properties": [{
"id": "skdlfkioajzzf",
"name": "Population",
"value": 1000
}, {
"id": "skdlfkioajzzg",
"name": "Weight",
"value": 72.41
}, {
"id": "skdlfkioajzzh",
"name": "Appendages",
"values": [{
"id": "skdlfkioajzzi",
"name": "Legs",
"value": 2
}, {
"id": "skdlfkioajzzj",
"name": "Heads",
"value": 1
}]
}, {
"id": "skdlfkioajzzk",
"name": "Species",
"value": "Human"
}]
}
序列化代码
string json;
try
{
Product product = JsonConvert.DeserializeObject<Product>(json);
var reserializedJson = JsonConvert.SerializeObject(product, new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
Product redeserializedJson = JsonConvert.DeserializeObject<Product>(reserializedJson);
Debug.Log(reserializedJson);
}
catch (Exception e)
{
Debug.Log(e.Message);
}
产品型号
public class Product
{
public string Id { get; set; }
public List<ProductPropertyValue> Properties { get; set; }
}
ProductPropertyValue类
public class ProductPropertyValue
{
[JsonProperty("id")]
public string PropertyId { get; set; }
[JsonProperty("value")]
public PropertyValue ValueObject { get; set;
}
PropertyValue模型
[JsonConverter(typeof(PropertyValueConverter))]
public class PropertyValue
{
public string StringValue { get; set; }
public int IntValue { get; set; }
public float FloatValue { get; set; }
public List<ProductPropertyValue> ListValue { get; set; }
public PropertyValue()
{
IntValue = int.MaxValue;
FloatValue = float.MaxValue;
}
[JsonIgnore]
public string Value
{
get
{
if (IntValue != int.MaxValue)
{
return IntValue.ToString();
}
if (FloatValue != float.MaxValue)
{
return FloatValue.ToString();
}
return StringValue;
}
}
}
PropertyValueConverter模型
public class PropertyValueConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(PropertyValue));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jObject = JToken.Load(reader);
PropertyValue propertyValue = new PropertyValue();
switch (reader.TokenType)
{
case JsonToken.Float:
propertyValue.FloatValue = jObject.ToObject<float>();
break;
case JsonToken.Integer:
propertyValue.IntValue = jObject.ToObject<int>();
break;
case JsonToken.String:
propertyValue.StringValue = jObject.ToObject<string>();
break;
case JsonToken.EndArray:
case JsonToken.StartArray:
propertyValue.ListValue = new List<ProductPropertyValue>();
List<JToken> tokens = jObject.ToList();
foreach (JToken token in tokens)
{
ProductPropertyValue prop = token.ToObject<ProductPropertyValue>();
if (prop != null)
{
propertyValue.ListValue.Add(prop);
}
}
break;
}
return propertyValue;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
try
{
serializer.Serialize(writer, value);
}
catch (JsonWriterException)
{
Debug.Log("caught json writer exception");
}
catch (Exception e)
{
Debug.Log("caught exception " + e.Message);
}
}
}
答案 0 :(得分:1)
好的,我解决了崩溃问题!问题是我的自定义JsonConverter一直在无限循环中调用自己。我必须将[JsonConverter(typeof(PropertyValueConverter))]
注释从PropertyValue模型移动到ProductPropertyValue模型。
这就是我现在的代码:
ProductPropertyValue类
public class ProductPropertyValue
{
[JsonProperty("id")]
public string PropertyId { get; set; }
[JsonProperty("value")]
[JsonConverter(typeof(PropertyValueConverter))]
public PropertyValue ValueObject { get; set;
}
PropertyValue模型
public class PropertyValue
{
public string StringValue { get; set; }
public int IntValue { get; set; }
public float FloatValue { get; set; }
public List<ProductPropertyValue> ListValue { get; set; }
public PropertyValue()
{
IntValue = int.MaxValue;
FloatValue = float.MaxValue;
}
[JsonIgnore]
public string Value
{
get
{
if (IntValue != int.MaxValue)
{
return IntValue.ToString();
}
if (FloatValue != float.MaxValue)
{
return FloatValue.ToString();
}
return StringValue;
}
}
}