2011-10-25 22 views
157

Estoy intentando deserializar una llamada API de gráficos de amigos de Facebook a una lista de objetos. El objeto JSON se ve así:Deserializar JSON con C#

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

No funciona porque el objeto primitivo no es válido.
¿Cómo puedo deserializar esto?

+1

escribe un deserializador personalizado específicamente para atender a tal json ... –

+1

o puede usar un 'Diccionario ', visita: http://stackoverflow.com/questions/7699972/how-to-decode-a-json-string-using-c/7701070#7701070 – Kakashi

+3

Tu amigo: http://json2csharp.com/ – nawfal

Respuesta

204

Es necesario crear una estructura como esta:

public class Friends 
{ 

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

public class FacebookFriend 
{ 

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

, entonces debería ser capaz de hacer:

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

nombres de mis clases son sólo un ejemplo. Debes usar nombres propios.

Adición de prueba de muestra:

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

Produce:

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

Sí, es lo que no sé quiero hacer, crear un nuevo objeto para mantener los hijos. Creo que voy a subscribir el JSON sacando el objeto primitivo. Gracias. –

+0

@Kevin Holditch gracias por la corrección. Extrañé un bit importante :) – Icarus

+0

result.Substring (8, result.Length - 9) hace el trabajo. Feo, pero ... –

14

Estoy de acuerdo con Ícaro (habría comentado si pudiera), pero en lugar de utilizar un clase CustomObject, I usaría un Dictionary (en caso de que Facebook agregue algo).

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

o

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

El uso dinámico funciona mejor en las nuevas versiones. 'public IList > data {get; conjunto; } ' – BJury

23

muy fácilmente podemos analizar JSON con la ayuda del diccionario y JavaScriptSerializer. aquí está el código de ejemplo por el cual analizo json del archivo 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(); 
+1

Esta solución es muy útil si no tiene el tiempo o la necesidad de crear contratos de datos. Especialmente si le interesan solo unos pocos atributos enterrados en la estructura JSON. En esa situación, puede usar una serie de declaraciones para navegar a lo que necesita. Nota: el tipo a deserializar también podría ser uno de los siguientes: Diccionario o ArrayList (cuando un nodo tiene una estructura repetitiva). –

+1

Obtengo una excepción de tiempo de ejecución con esto: no se define ningún constructor sin parámetros para el tipo de 'System.String' en la línea de código Deserialize. –

36

veces prefiero objetos dinámicos

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

Un ejemplo de una instancia en la que esto fue útil fue cuando el objeto en el que intentaba deserializar contenía una propiedad que era una interfaz – soupy1976

12

Newtonsoft.JSON es una buena solución para este tipo de situaciones. También Newtonsof.JSON es más rápido que otros como JavaScriptSerializer, DataContractJsonSerializer.

En esta muestra, se puede lo siguiente:

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

Entonces usted puede echar jsonData a JArray y se puede utilizar para el bucle para obtener datos en cada iteración. Además, quiero agregar algo.

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

Trabajar con objetos dinámicos y usar la serialización de Newtonsoft es una buena opción.

12

Una gran manera de generar automáticamente estas clases para usted es copiar su salida JSON y tirarlo aquí:

http://json2csharp.com/

Se le proporcionará un punto de partida para retocar sus clases de deserialización .

Cuestiones relacionadas