Deserialize JSON with C#

Próbuję deserializować wywołanie API Facebook friends graph na listę obiektów. Obiekt JSON wygląda następująco:

{"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);

To nie działa, ponieważ prymitywny obiekt jest nieprawidłowy.
Jak mogę to deserializować?

 170
Author: Markus Safar, 2011-10-26

6 answers

Musisz utworzyć taką strukturę:

public class Friends
{

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

public class FacebookFriend
{

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

Wtedy powinieneś być w stanie zrobić:

Friends facebookFriends = new JavaScriptSerializer().Deserialize<Friends>(result);
Nazwy moich klas są tylko przykładem. Powinieneś używać właściwych imion.

Dodanie przykładowego testu:

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

Produkuje:

id: 518523721, name: ftyft
id: 527032438, name: ftyftyf
id: 527572047, name: ftgft
id: 531141884, name: ftftft
 222
Author: Icarus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-10 13:28:22

Czasami wolę obiekty dynamiczne

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);
}
 39
Author: Bishoy Hanna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-01 14:40:26

Bardzo łatwo możemy parsować json za pomocą dictionary i JavaScriptSerializer. oto przykładowy kod, za pomocą którego analizuję json z pliku ashx.

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();
 24
Author: Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-01 14:43:21

Świetnym sposobem na automatyczne generowanie tych klas jest skopiowanie wyjścia JSON i wrzucenie go tutaj:

Http://json2csharp.com/

Dostarczy Ci punktu wyjścia, aby poprawić swoje klasy do deserializacji.

 17
Author: Jack Fairfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-17 22:05:50

Zgadzam się z Ikarem (skomentowałbym gdybym mógł), ale zamiast używać klasy CustomObject , Użyłbym słownika (na wypadek, gdyby facebook coś dodał).

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

Lub

private class MyFacebookClass
{
   public IList<IDictionary<string, object>> data { get; set; }
}
 14
Author: Stijn Bollen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-21 14:44:10

Newtonsoft.JSON jest dobrym rozwiązaniem na tego typu sytuacje. Również Newtonsof.JSON jest szybszy od innych, takich jak JavaScriptSerializer, DataContractJsonSerializer.

W tej próbce można:

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

Następnie możesz rzucić jsonData do JArray i możesz użyć pętli for, aby uzyskać dane przy każdej iteracji. Chcę też coś dodać.

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

Praca z dynamicznym obiektem i korzystanie z Newtonsoft serialize jest dobrym wyborem.

 13
Author: OnurBulbul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-02 07:36:53