2010-11-11 8 views
0

J'ai les données JSON comme montré ci-dessous. J'ai seulement inclus les noms de colonnes une fois pour enregistrer la taille des données. S'il vous plaît laissez-moi savoir comment puis-je la convertir en liste d'objets C#.Comment désérialiser le texte json à la liste d'objets en C# en utilisant JsonConvert.DeserializeObject

// JSON 
{ 
    "COLUMNS": [ 
     "id", "country","lastname", "firstname", "email", "category" 
    ], 
    "DATA": [ 
     [43, "USA", "jon", "doe", "[email protected]", "HR"], 
     [44, "JAPAN", "tanaka", "yidi", "[email protected]", "IT"] 
    ] 
} 

// .NET 
Employee emp = JsonConvert.DeserializeObject<Employee>(jsonData); 

Je devrais pouvoir accéder aux propriétés d'objet comme emp.lastname.

Aussi, comme le titre l'indique, j'utilise le JsonConvert class dans le Json.NET library.

Répondre

1

Vous ne pourrez pas utiliser la classe JsonConvert directement, car elle s'attend à ce que toutes les propriétés aient un nom/mappage et ne puissent pas le déterminer car vous utilisez essentiellement un format personnalisé.

Ce que vous devez faire est de créer une classe qui a les colonnes et les données et sérialisation en cela, comme ceci:

class CustomData 
{ 
    public string Columns { get; set; } 
    public object[,] Data { get; set; } 
} 

JsonConvert devrait être en mesure de convertir vos données dans cette structure. NET. De là, il devient plus d'un problème de .NET, en ce que vous devez obtenir les noms des colonnes et des données. Vous devriez être en mesure d'utiliser LINQ pour aider à jumeler les deux et ensuite utiliser la réflexion pour remplir votre article:

// The custom data structure, deserialized from JSON. 
CustomData data = ...; 

// The type of Employee. 
Type type = typeof(Employee); 

// Create a map of the property info to the ordinal in the 
// Columns. 
IDictionary<int, PropertyInfo> propertyMap = data.Columns. 
    Select((p, i) => 
     new { Index = i, PropertyInfo = type.GetProperty(p) }). 
    ToDictionary(p => p.Index, p => p.PropertyInfo); 

// Cycle through the rows in the data. 
var query = 
    // Cycle through all of the rows. 
    from row in Enumerable.Range(0, data.Data.GetLength(0)) 

    // Create the instance. 
    let instance = new Employee() 

    // For each column in the row. 
    from column in Enumerable.Range(0, data.Data.GetLength(1)) 

    // Lookup the property info. 
    let propertyInfo = propertyMap[column] 

    // Select the instance, the property, and the value. 
    select { 
     // This is used for grouping purposes, since 
     // you can't guarantee that the type you are serializing 
     // to will have natural identity properties and 
     // you know the row corresponds to one singular instance. 
     Row = row, 
     Instance = instance, 
     PropertyInfo = propertyInfo, 
     Value = data.Data[row, column] 
    }; 

// Iterate through the items, setting the instance values. 
foreach (var propertyAndData in query) 
{ 
    // Set the property value on the instance. 
    propertyAndData.PropertyInfo. 
     SetValue(propertyAndData.Instance, Value, null); 
} 

// Group by the row and get the first item in each sequence. 
IEnumerable<Employee> employees = 
    from item in query 
    groupby item by item.Row into g 
    select g.First(); 

La seule mise en garde pour ce qui précède; Si vous utilisez un type de valeur, alors et non peuplera la même instance que celle que vous parcourez. Pour gérer les types de valeurs, vous devez dérouler la requête LINQ et parcourir chaque ligne et colonne à l'aide de boucles, en créant la nouvelle instance sur chaque nouvelle ligne, puis en utilisant Reflection comme indiqué ci-dessus pour remplir les propriétés.

Questions connexes