2015-04-01 515 views
2

我正在使用JSON.NET將某些數據解析爲某些使用反射的特定屬性。'Newtonsoft.Json.Linq.JObject'類型的對象無法轉換爲類型

property.SetValue(comInstance, field.Value);

一個這條線它將引發ArgumentException

類型 'System.ArgumentException' 的未處理的異常出現在mscorlib.dll

其他信息:類型的對象「Newtonsoft .Json.Linq.JObject'不能轉換爲類型'Microsoft.Xna.Framework.Vector2'。

我知道這必須是與我JsonConverterVector2類型,它看起來像這樣:

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(); 

    } 
} 

現在,我發現寫被調用,但讀從來不會。 我反序列化這樣的:

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,異常狀態:

不能鑄造。

+0

JSON轉換器是否拋出異常?我沒有看到代碼行'property.SetValue(comInstance,field.Value);'轉換器中的任何地方。 – dbc 2015-04-01 20:09:09

+0

你的'EntityJson'類是什麼樣的?該類中的Vector2的屬性名稱是否與您正在反序列化的JSON中的屬性名稱相匹配? – 2015-04-01 20:11:49

+0

您需要向我們展示調用了'property.SetValue(comInstance,field.Value);'的代碼。但是如果'field.Value'是一個'JObject',並且你在一個更高級別的JSON轉換器中,你需要將它轉換爲目標類型,例如['JToken.ToObject Method(Type,JsonSerializer)']( http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JToken_ToObject_1.htm) – dbc 2015-04-01 20:17:45

回答

0

好,香港專業教育學院設法解決它這樣做:

object result = field.Value; 
if (field.Value.GetType() == typeof(JObject)) 
{ 
     JToken token = (JToken)field.Value; 
     result = token.ToObject(property.PropertyType, JsonSerializer.Create(JsonUtility.Settings)); 
} 
else 
{ 
     result = Convert.ChangeType(result, property.PropertyType); 
} 

property.SetValue(comInstance, result); 

這是一個穩定的解決方案嗎?

+0

如果您試圖將JSON片段應用於預先存在的對象,可以使用[JsonConvert .PopulateObject](http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_JsonConvert_PopulateObject_1.htm)並讓Json.NET爲您做反射。 – dbc 2015-04-01 22:58:20

+3

_「這是一個**穩定的**解決方案嗎?」 - 這可以說是一個新的** _question_ – MickyD 2015-04-02 00:25:52

+0

@MickyDuncan:這聽起來比SO更接近[CodeReview.SE]。 – 2015-04-02 03:03:04

相關問題