Converting JSON Arrays to Lists of Objects in C#: Structural Matching and Deserialization Practices

Dec 02, 2025 · Programming · 32 views · 7.8

Keywords: C# | JSON Deserialization | JSON.NET

Abstract: This article delves into the challenges of JSON deserialization in C# using the JSON.NET library, focusing on how to properly match JSON structures with C# class definitions. Through a concrete case study, it analyzes how to adjust class definitions to use Dictionary<string, T> instead of List<T> when JSON contains nested objects rather than arrays, and introduces a Wrapper class to correspond to outer JSON objects. It explains the application of JsonProperty attributes, deserialization steps, and provides complete code examples and debugging tips to help developers avoid common null value issues and ensure accurate data conversion.

Structural Matching Issues in JSON Deserialization

In C# development, using the JSON.NET (Newtonsoft.Json) library for JSON deserialization is common, but developers often encounter null values or errors due to mismatches between JSON structures and C# class definitions. Based on a real-world case, this article explores how to resolve such issues by adjusting class definitions.

Case Analysis and Problem Diagnosis

The user's JSON string includes an outer object JsonValues with id and values properties. Here, values is an object containing key-value pairs like value1 and value2, each with id and diaplayName (note the typo) properties. In the initial C# class definition, the ValueSet class defines values as List<Value>, assuming values in JSON is an array. However, the actual JSON has values as an object, causing the values property to be null during deserialization.

Solution: Adjusting Class Definitions to Match JSON Structure

To deserialize correctly, modify the class definitions to reflect the actual JSON structure. First, add a Wrapper class corresponding to the outer JSON object:

class Wrapper
{
    [JsonProperty("JsonValues")]
    public ValueSet ValueSet { get; set; }
}

In the ValueSet class, change the values property from List<Value> to Dictionary<string, Value>, since values in JSON is a key-value object, not an array:

class ValueSet
{
    [JsonProperty("id")]
    public string Id { get; set; }
    [JsonProperty("values")]
    public Dictionary<string, Value> Values { get; set; }
}

The Value class requires JsonProperty attributes to map JSON fields, handling spelling differences (e.g., diaplayName):

class Value
{
    [JsonProperty("id")]
    public string Id { get; set; }
    [JsonProperty("diaplayName")]
    public string DisplayName { get; set; }
}

Deserialization Implementation and Code Example

Use the modified classes for deserialization:

string jsonString = @"
{
    \"JsonValues\": {
        \"id\": \"MyID\",
        \"values\": {
            \"value1\": {
                \"id\": \"100\",
                \"diaplayName\": \"MyValue1\"
            },
            \"value2\": {
                \"id\": \"200\",
                \"diaplayName\": \"MyValue2\"
            }
        }
    }
}";
var valueSet = JsonConvert.DeserializeObject<Wrapper>(jsonString).ValueSet;

This code correctly parses the JSON, with valueSet.Id as "MyID" and valueSet.Values as a dictionary containing two key-value pairs, accessible via iteration:

Console.WriteLine("id: " + valueSet.Id);
foreach (KeyValuePair<string, Value> kvp in valueSet.Values)
{
    Console.WriteLine(kvp.Key + " id: " + kvp.Value.Id);
    Console.WriteLine(kvp.Key + " name: " + kvp.Value.DisplayName);
}

Supplementary References and Best Practices

Other answers provide additional insights. For example, using online tools like json2csharp.com can auto-generate matching C# classes, but manual verification and adjustments are needed. Ensure the JSON string is read correctly (e.g., with StreamReader.ReadToEnd()) and check the deserialization type (e.g., use ValueSet instead of List<ValueSet> unless JSON is an array). The core is understanding JSON structure (object vs. array) and designing classes accordingly, leveraging JsonProperty to handle naming differences.

Conclusion

By precisely matching JSON structures with C# class definitions, null value issues in deserialization can be effectively avoided. Use Dictionary<string, T> for object key-value pairs, introduce a Wrapper class for outer JSON objects, and utilize property mapping to ensure field alignment. This enhances code robustness and maintainability, suitable for complex JSON data processing scenarios.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.