2013-04-02 49 views
1

我使用RestSharp,并且在反序列化Json时出现问题。如何在不知道格式的情况下反序列化json?

在成功的情况下,收到一个JSON那样(数据是一个表):

{"status": "OK", "data": "[...]"} 

并且在错误的情况下,收到一个JSON等(数据是一个字符串):

{"status": "ERROR", "data": "..."} 

我怎么能知道,如果我有一个表或用绳子反序列化JSON的?

我的方法是类似的东西(它返回一个表,但崩溃,如果将JSON返回一个字符串数据):

public Task<Items> GetItemById(string id) 
{ 
var client = 
new RestClient(string.Format("{0}/{1}/{2}/{3}/{4}", _baseUrl, 
    AppResources.RestApiVersion, userId, token, AppResources.NotUse)); 

var tcs = new TaskCompletionSource<Items>(); 
var request = new RestRequest(string.Format("/items/get/{0}", id)); 
client.ExecuteAsync<Items>(request, response => { 
    try 
    { 
     tcs.SetResult(new JsonDeserializer().Deserialize<Items>(response)); 
    } 
    catch (InvalidCastException e) 
    { 

    } 
}); 
return tcs.Task; 
} 

回答

0

我使用代码从这样的回答:Deserialize JSON into C# dynamic object?

它会生成一个动态对象取决于JSON对象的内容。我喜欢它了不少,虽然他的代码中有几个错误,我已经固定在下面我的版本:

internal sealed class DynamicJsonConverter : JavaScriptConverter 
{ 
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) 
    { 
     if (dictionary == null) 
      throw new ArgumentNullException("dictionary"); 

     return type == typeof(object) ? new DynamicJsonObject(dictionary) : null; 
    } 

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override IEnumerable<Type> SupportedTypes 
    { 
     get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); } 
    } 

    #region Nested type: DynamicJsonObject 

    private sealed class DynamicJsonObject : DynamicObject 
    { 
     private readonly IDictionary<string, object> _dictionary; 

     public DynamicJsonObject(IDictionary<string, object> dictionary) 
     { 
      if (dictionary == null) 
       throw new ArgumentNullException("dictionary"); 
      _dictionary = dictionary; 
     } 

     public override string ToString() 
     { 
      var sb = new StringBuilder(); 
      ToString(sb); 
      return sb.ToString(); 
     } 

     private void ToString(StringBuilder sb) 
     { 
      sb.Append("{"); 
      var firstInDictionary = true; 
      foreach (var pair in _dictionary) 
      { 
       if (!firstInDictionary) 
        sb.Append(","); 
       firstInDictionary = false; 
       var value = pair.Value; 
       var name = pair.Key; 
       if (value is string) 
       { 
        sb.AppendFormat("\"{0}\":\"{1}\"", name, value); 
       } 
       else if (value is IDictionary<string, object>) 
       { 
        sb.AppendFormat("\"{0}\":", name); 
        new DynamicJsonObject((IDictionary<string, object>)value).ToString(sb); 
       } 
       else if (value is ArrayList) 
       { 
        sb.Append("\""); 
        sb.Append(name); 
        sb.Append("\":["); 
        var firstInArray = true; 
        foreach (var arrayValue in (ArrayList)value) 
        { 
         if (!firstInArray) 
          sb.Append(","); 
         firstInArray = false; 
         if (arrayValue is IDictionary<string, object>) 
          new DynamicJsonObject((IDictionary<string, object>)arrayValue).ToString(sb); 
         else if (arrayValue is string) 
          sb.AppendFormat("\"{0}\"", arrayValue); 
         else 
          sb.AppendFormat("{0}", arrayValue); 

        } 
        sb.Append("]"); 
       } 
       else 
       { 
        sb.AppendFormat("\"{0}\":{1}", name, value); 
       } 
      } 
      sb.Append("}"); 
     } 

     public override bool TryGetMember(GetMemberBinder binder, out object result) 
     { 
      if (!_dictionary.TryGetValue(binder.Name, out result)) 
      { 
       // return null to avoid exception. caller can check for null this way... 
       result = null; 
       return true; 
      } 

      var dictionary = result as IDictionary<string, object>; 
      if (dictionary != null) 
      { 
       result = new DynamicJsonObject(dictionary); 
       return true; 
      } 

      var arrayList = result as ArrayList; 
      if (arrayList != null && arrayList.Count > 0) 
      { 
       if (arrayList[0] is IDictionary<string, object>) 
        result = new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x))); 
       else 
        result = new List<object>(arrayList.Cast<object>()); 
      } 

      return true; 
     } 
    } 

    #endregion 
} 

他的代码示例的其余部分是适用的。

+0

嗯,你真的不希望只是反序列化的列表,虽然。要反序列化列表,您必须反序列化列表的内容,这将是具有非列表属性的对象。我的意思是,如果主要对象,你只想列表对象,你可以创建你'的ToString(增加一个静态的“深度”变量)'(这是递归)和增量深度的ToString(的'开头)'和在末尾递减它,并且只在depth> 0时处理第一个和第二个if语句。第三个if(else if(value是ArrayList)')处理列表。 – Pete

相关问题