JSONをC#で逆シリアル化する


206

Facebookの友達のGraph API 呼び出しをオブジェクトのリストに逆シリアル化しようとしています。JSONオブジェクトは次のようになります。

{"data":[{"id":"518523721","name":"ftyft"},
         {"id":"527032438","name":"ftyftyf"},
         {"id":"527572047","name":"ftgft"},
         {"id":"531141884","name":"ftftft"},
         {"id":"532652067","name"...

List<EFacebook> facebooks = new JavaScriptSerializer().Deserialize<List<EFacebook>>(result);

プリミティブオブジェクトが無効であるため、機能していません。これを逆シリアル化するにはどうすればよいですか?


3
そのようなjsonに対応するために特別にカスタムデシリアライザを記述します...
ashutosh raina

2
またはあなたが使用することができDictionary<string,string>、チェックアウト:stackoverflow.com/questions/7699972/...
カカシ

9
あなたの友達:json2csharp.com
nawfal

4
(インストールされているWebツールと2013、または2012のような)この正確な機能が組み込まれてい実際に視覚的なスタジオ:編集> JSONとしてクラスを貼り付け>貼り付け
floomby

回答:


264

次のような構造を作成する必要があります。

public class Friends
{

    public List<FacebookFriend> data {get; set;}
}

public class FacebookFriend
{

    public string id {get; set;}
    public string name {get; set;}
}

それからあなたはできるはずです:

Friends facebookFriends = new JavaScriptSerializer().Deserialize<Friends>(result);

私のクラスの名前はほんの一例です。適切な名前を使用する必要があります。

サンプルテストの追加:

string json =
    @"{""data"":[{""id"":""518523721"",""name"":""ftyft""}, {""id"":""527032438"",""name"":""ftyftyf""}, {""id"":""527572047"",""name"":""ftgft""}, {""id"":""531141884"",""name"":""ftftft""}]}";

Friends facebookFriends = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Friends>(json);

foreach(var item in facebookFriends.data)
{
    Console.WriteLine("id: {0}, name: {1}", item.id, item.name);
}

生成する:

id: 518523721, name: ftyft
id: 527032438, name: ftyftyf
id: 527572047, name: ftgft
id: 531141884, name: ftftft

3
ええ、私がしたくないのは、子を保持する新しいオブジェクトを作成することです。私はプリミティブオブジェクトを取り出すjsonを部分文字列化すると思います。ありがとうございました。

@Kevin Holditch、訂正ありがとうございます。私は1つの重要なビットを逃しました:)
イカルス'25年

2
このSystem.Web.Script.Serialization.JavaScriptSerializer()について私が気に入らないのは、常に定義された型Tが必要なことです。Javaには、このorg.javaライブラリ(パッケージ)があり、すべて匿名のままです: "JSONObject [" param "]。JSONarray(5)"など
スポーツ

2
idプロパティとnameプロパティのセッターはパブリックのままにしておく必要があることに注意してください。それらがプライベートまたは保護に設定されている場合、逆シリアル化はエラーなしで実行されますが、すべてのデータはnullになります。
Isaac Zais

2
@sportsでは、動的に逆シリアル化することでC#でそれを行うことができますが、既知の型に逆シリアル化するとパフォーマンスが大幅に向上します。
PRMan

50

時々私は動的オブジェクトを好む:

public JsonResult GetJson()
{
  string res;
  WebClient client = new WebClient();

  // Download string
  string value = client.DownloadString("https://api.instagram.com/v1/users/000000000/media/recent/?client_id=clientId");

  // Write values
  res = value;
  dynamic dyn = JsonConvert.DeserializeObject(res);
  var lstInstagramObjects = new List<InstagramModel>();

  foreach(var obj in dyn.data)
  {
    lstInstagramObjects.Add(new InstagramModel()
    {
      Link = (obj.link != null) ? obj.link.ToString() : "",
      VideoUrl = (obj.videos != null) ? obj.videos.standard_resolution.url.ToString() : "",
      CommentsCount = int.Parse(obj.comments.count.ToString()),
      LikesCount = int.Parse(obj.likes.count.ToString()),
      CreatedTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds((double.Parse(obj.created_time.ToString()))),
      ImageUrl = (obj.images != null) ? obj.images.standard_resolution.url.ToString() : "",
      User = new InstagramModel.UserAccount()
             {
               username = obj.user.username,
               website = obj.user.website,
               profile_picture = obj.user.profile_picture,
               full_name = obj.user.full_name,
               bio = obj.user.bio,
               id = obj.user.id
             }
    });
  }

  return Json(lstInstagramObjects, JsonRequestBehavior.AllowGet);
}

これが有用だった例の1つは、逆シリアル化しようとしているオブジェクトにインターフェイスであるプロパティが含まれていたときでした
soupy1976

2
説明が正しいでしょう。
Peter Mortensen

@Icarusが承認した回答よりも、なぜこれを好むのですか?
質問

@Questioning、強力な型のクラスへの逆シリアル化では、クラスにないプロパティは無視されますが、動的オブジェクトへの逆シリアル化では、クラスを更新する必要なく、将来作成される新しいプロパティに柔軟な動的.Netオブジェクトが返されます。(私が言ったように、時々標準的ではない)
ビショイ・ハンナ


28

非常に簡単に、辞書とJavaScriptSerializerを使用してJSONコンテンツを解析できます。以下は、ashxファイルからJSONコンテンツを解析するサンプルコードです。

var jss = new JavaScriptSerializer();
string json = new StreamReader(context.Request.InputStream).ReadToEnd();
Dictionary<string, string> sData = jss.Deserialize<Dictionary<string, string>>(json);
string _Name = sData["Name"].ToString();
string _Subject = sData["Subject"].ToString();
string _Email = sData["Email"].ToString();
string _Details = sData["Details"].ToString();

3
このソリューションは、時間がない場合、またはデータコントラクトを作成する必要がない場合に非常に役立ちます。特に、JSON構造の奥深くに埋め込まれているいくつかの属性のみに関心がある場合。そのような状況では、一連のステートメントを使用して、必要なものに移動できます。注:逆シリアル化する型は、次のいずれかになる場合もあります。Dictionary<string、object>またはArrayList(ノードに繰り返し構造がある場合)。
Philippe Monnet

1
これにより、ランタイム例外が発生します。コードのDeserialize行の「System.String」のタイプにパラメーターなしのコンストラクターが定義されていません。
RSK

20

Newtonsoft.JSONこのような状況に適したソリューションです。また、Newtonsof.JSON高速化などの他、よりJavaScriptSerializerDataContractJsonSerializer

このサンプルでは、​​次のことができます。

var jsonData = JObject.Parse("your JSON data here");

次にJArray、jsonDataをにキャストし、forループを使用して各反復でデータを取得できます。

また、何かを追加したい:

for (int i = 0; (JArray)jsonData["data"].Count; i++)
{
    var data = jsonData[i - 1];
}

動的オブジェクトの操作とNewtonsoft serializeの使用は良い選択です。


15

私はIcarusに同意します(できればコメントしたはずです)が、CustomObjectクラスを使用する代わりに、辞書を使用します(Facebookが何かを追加する場合)。

private class MyFacebookClass
{
    public IList<IDictionary<string, string>> data { get; set; }
}

または

private class MyFacebookClass
{
    public IList<IDictionary<string, object>> data { get; set; }
}

3
新しいバージョンでは、動的を使用する方が効果的です。public IList<IDictionary<string, dynmaic>> data { get; set; }
BJury 2014

3

シリアル化:

// Convert an object to JSON string format
string jsonData = JsonConvert.SerializeObject(obj);

Response.Write(jsonData);

逆シリアル化::

動的オブジェクトを逆シリアル化するには

  string json = @"{
      'Name': 'name',
      'Description': 'des'
    }";

var res = JsonConvert.DeserializeObject< dynamic>(json);

Response.Write(res.Name);

3

この拡張機能を使用できます

public static class JsonExtensions
{
   public static T ToObject<T>(this string jsonText)
   {
       return JsonConvert.DeserializeObject<T>(jsonText);
   }

   public static string ToJson<T>(this T obj)
   {
       return JsonConvert.SerializeObject(obj);
   }
}


1

あなたが使用している場合、.NETのコア 3.0は、使用することができますSystem.Text.Json JSONをデシリアライズするために(今ビルトインされています)。

最初のステップは、JSONをモデル化するクラスを作成することです。これを助けることができる多くのツールがあり、ここの答えのいくつかはそれらをリストします。

一部のオプションは、http ://json2csharp.com、http: //app.quicktype.io、またはVisual Studioを使用します(メニュー編集貼り付け →はクラスとしてJSONを貼り付けを)。

public class Person
{
    public string Id { get; set; }
    public string Name { get; set; }
}

public class Response
{
    public List<Person> Data { get; set; }
}

次に、次を使用して逆シリアル化できます。

var people = JsonSerializer.Deserialize<Response>(json);

camelCase処理などの設定を追加する必要がある場合は、次のようにシリアライザ設定をデシリアライザに渡します。

var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var person = JsonSerializer.Deserialize<Response>(json, options);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.