3

デシリアライズする必要がある次のJson文字列があります。

{"123456789":
  {"short_description":"Delivered",
     "detail_description":"Your item has been delivered"
   }
}

最初のフィールド「123456789」はID番号であるため、基本的にこの値は、照会するデータによって異なる場合があります。

Visual StudioでC#を使用しています。明らかに、最初のフィールドの値は変更される可能性があるため、事前定義されたクラスを使用してJSONを逆シリアル化することはできません。これは、このフィールドがクラス名として使用されますが、フィールド値がクラス名と一致しないためです。

これをある種の動的クラスに逆シリアル化するが、それでも事前定義されたクラスであるかのようにフィールドにアクセスする方法はありますか?

あるいは、クラス名が一致していなくても、これを事前定義されたクラスに逆シリアル化する方法はありますか?

このデータを提供するサービスはサードパーティのものであるため、私はそれを制御することはできません。

4

2 に答える 2

5

これが私が本番コードで使用する1つの方法です。それは完璧ではないかもしれませんが、それは仕事を成し遂げます。

using using System.Web.Script.Serialization;

// .....

    public object GetJson(string url)
    {
        var json = Get(url); // I have code that makes this work, it gets a JSON string

        try
        {
            var deserializer = new JavaScriptSerializer();
            var result = deserializer.DeserializeObject(json);

            return result;
        }
        catch (ArgumentException e)
        {
            // Error handling....
        }            
    }

返されるオブジェクトは、JSONの構造に応じて、一般的なMap、Listなどになります。予想される構造がわかっている場合、これは、カスタマイズされたパーサーやターゲットオブジェクトタイプを記述しなくても非常に役立ちます。

次に、たとえば、マップのキーを列挙して、変化するキーを見つけることができます。ラッパーまたは変換は、アプリケーション層の残りの部分に一貫したAPIを提供します。何かのようなもの:

public class Order {
     public string OrderNum { private set; get; }
     public string ShortDesc { private set; get; }
     public string Desc { private set; get; }

     public static Order FromJson(object jsonResult) 
     {
          var m = jsonResult as Map<string, object>;

          // Handle errors, but I am not

          var firstPair = m.First();

          var detail = firstPair.Value as Map<string, object>;

          var dummy = new Order()
          {
              OrderNum = firstPair.Key,
              ShortDesc = detail["short_description"].ToString();
              Desc = detail["detail_description"].ToString();
          }

          return dummy;
     }
}
于 2012-11-22T02:08:39.653 に答える
3

上記の回答が気に入ったので、少しリファクタリングしました。とへの参照が必要にSystem.Web.Extensions.dllなりSystem.Web.Script.Serializationます。

クラスは次のとおりです。

public class Order
{
    public string OrderNum { private set; get; }
    public string ShortDesc { private set; get; }
    public string Desc { private set; get; }

    public static Order FromJson(string jsonResult) 
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        // Should deserialize right to Dictionary<string, object>
        // var result = ((Dictionary<string, object>)js.Deserialize<dynamic>(jsonResult)).First();
        var result = js.Deserialize<Dictionary<string, object>>(jsonResult).First();
        var detail = (Dictionary<string, object>)result.Value;

        return new Order()
        {
            OrderNum = result.Key,
            ShortDesc = detail["short_description"].ToString(),
            Desc = detail["detail_description"].ToString()
        };
    }
}

そしてそれを呼び出す方法:

string json = "{\"123456789\": {\"short_description\":\"Delivered\", \"detail_description\":\"Your item has been delivered\" } }";
Order o = Order.FromJson(json);

ただし、エラー処理は自分で実装する必要があります。

于 2012-11-22T02:42:35.173 に答える