【发布时间】:2015-04-01 20:03:13
【问题描述】:
我正在使用 JSON.NET 通过反射将一些数据解析为一些特定的属性。
property.SetValue(comInstance, field.Value);
这一行会抛出一个ArgumentException:
在 mscorlib.dll 中发生了“System.ArgumentException”类型的未处理异常
附加信息:“Newtonsoft.Json.Linq.JObject”类型的对象无法转换为“Microsoft.Xna.Framework.Vector2”类型。
我知道这一定与我的JsonConverter 的Vector2 类型有关,看起来像这样:
public class Vector2Converter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Vector2));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jsonObject = JObject.Load(reader);
var properties = jsonObject.Properties().ToList();
return new Vector2
{
X = (float)properties[0].Value,
Y = (float)properties[1].Value
};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Vector2 v = (Vector2)value;
writer.WriteStartObject();
writer.WritePropertyName("X");
serializer.Serialize(writer, v.X);
writer.WritePropertyName("Y");
serializer.Serialize(writer, v.Y);
writer.WriteEndObject();
}
}
现在,我注意到 write 被调用,但 read 从来没有。 我这样反序列化:
JsonConvert.DeserializeObject<EntityJson>(json, JsonUtility.Settings);
JsonUility.Settings 包含Vector2Converter。
我这样序列化:
JsonConvert.SerializeObject(entityJson, Formatting.Indented, JsonUtility.Settings);
JSON 本身的字段看起来也不错:
"Center": {
"X": 116.0,
"Y": 65.0
},
谁能帮帮我?
编辑:
internal class EntityJson
{
public string Name { get; set; }
public Dictionary<string, ComponentJson> Components { get; set; }
public EntityJson()
{
Components = new Dictionary<string, ComponentJson>();
}
public Entity ToEntity()
{
Entity entity = new Entity(Name);
foreach(KeyValuePair<string, ComponentJson> com in Components)
{
ObjectHandle handle = Activator.CreateInstance(com.Value.Namespace, com.Value.Namespace +"."+ com.Key);
Object handleValue = handle.Unwrap();
Component comInstance = (Component)handleValue;
foreach(KeyValuePair<string, object> field in com.Value.Fields)
{
PropertyInfo property = comInstance.GetType().GetProperty(field.Key,
BindingFlags.NonPublic |
BindingFlags.Public |
BindingFlags.Instance);
property.SetValue(comInstance, field.Value); // <-- field.Value
}
entity.AddUnsafe(comInstance);
}
return entity;
}
}
field.value 将是 JObject 而不是 Vector2,异常状态:
它不能被铸造。
【问题讨论】:
-
JSON 转换器是否抛出异常?我在转换器的任何地方都没有看到代码行
property.SetValue(comInstance, field.Value);。 -
您的
EntityJson班级是什么样的?该类中 Vector2 的属性名称是否与您要反序列化的 JSON 中的属性名称匹配? -
您需要向我们展示调用
property.SetValue(comInstance, field.Value);的代码。但是如果field.Value是JObject,并且您在某个更高级别的JSON 转换器中,则需要将其转换为目标类型,例如JToken.ToObject Method (Type, JsonSerializer) -
这是我的 EntityJson 的样子: