In this article, we will learn how to retrieve property names from a JSON object in C#. We can achieve this either through reflection or through one of the widely used JSON libraries such as Newtonsoft.Json and System.Text.Json

To download the source code for this article, you can visit our GitHub repository.

Let’s dive in!

Why Retrieve JSON Property Names?

The JSON format has become a de facto standard due to its readability and simplicity. Since it is a mapping of properties to data, JSON enables us to map .NET objects to JSON objects in a system-agnostic way. These JSON properties play a vital role during serialization and deserialization. Because of this we often require retrieving these properties when parsing JSON objects. Let’s see how we can accomplish this using Newtonsoft.Json and System.Text.Json.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

Retrieve JSON Property Names Using Newtonsoft.Json

First, let’s see how we can retrieve JSON properties using the popular Newtonsoft.Json library. To get started we need to add the NuGet package to our project:

dotnet add package Newtonsoft.Json

Using Newtonsoft.Json With Reflection

Here we are using the JsonProperty attribute from Newtonsoft.Json to add custom property names to our object properties. We can then retrieve those custom attributes via reflection. The JsonProperty attribute is often used to aid in mapping JSON properties into .NET objects. By default the property names themselves are used for serialization and deserialization. Sometimes the property names do not align perfectly with our standard naming conventions. In these situations we can employ the JsonProperty attribute to map between the two.

Let’s take a look at an example: 

public class Sales
{
    [JsonProperty("Slx_PER_Year")]
    public string? YearlySales { get; set; }

    [JsonProperty("Slx_PER_DAY")]
    public string? DailySales { get; set; }
}

In this example, we see that the JSON property names do not align with standard .NET property naming conventions. By using the JsonProperty attribute we preserve proper serialization and deserialization behavior whilst maintaining the naming convention in our code as per standards.

Now, let’s define a method to retrieve JSON property names via reflection:

public static IEnumerable<string> RetrievalUsingReflection(object obj)
{
    foreach (var property in obj.GetType().GetProperties())
    {
        var jsonProperty = property.GetCustomAttribute<JsonPropertyAttribute>();
        var jsonPropertyName = jsonProperty?.PropertyName; 

        yield return propertyName != null 
            ? jsonPropertyName 
            : property.Name;
    }
}

While iterating over the properties of the type of our obj we check for JsonPropertyAttribute and extract them. For each one found, we return the PropertyName value, otherwise we return the property name.

Let’s see how it works:

var sales = new Sales
{
    YearlySales = "365000",
    DailySales = "1000"
};

var propertyNames = JsonHelper.RetrievalUsingReflection(sales);

foreach (var propertyName in propertyNames)
{
    Console.WriteLine(propertyName);
}

We are using our sales instance to retrieve the JSON property names with our previously defined RetrievalUsingReflection() method and print the output of the result to the console:

Slx_PER_Year
Slx_PER_DAY

Using Newtonsoft.Json With Serialization

For this approach, we are using JsonConvert.DeserializeObject() method of Newtonsoft.Json library to retrieve the JSON property name:

public static IEnumerable<string> RetrievalUsingSerialization(object obj)
{
    string json = JsonConvert.SerializeObject(obj);

    var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
        
    return values != null 
        ? values.Keys 
        : Enumerable.Empty<string>();
}

We keep this implementation simple and serialize our obj to a string with JsonConvert.SerializeObject(). We then deserialize the JSON string to a Dictionary<string, object> with JsonConvert.DeserializeObject(). Using the dictionary Keys property we can now retrieve our property names.

Let’s repeat our example from the previous section using our new method:

var sales = new Sales
{
    YearlySales = "365000",
    DailySales = "1000"
};

var propertyNames = JsonHelper.RetrievalUsingSerialization(sales);

foreach (var propertyName in propertyNames)
{
    Console.WriteLine(propertyName);
}

Similarly, we call RetrievalUsingSerialization() on our sales object and observe the following output:

Slx_PER_Year
Slx_PER_DAY

Using Newtonsoft.Json With Contract Resolver

Here we are using  IContractResolver from Newtonsoft.Json to retrieve the JSON property name.

Let’s see how we can do this:

public static class ResolverHelper
{
    static readonly IContractResolver _defaultResolver = JsonSerializer.CreateDefault().ContractResolver;

    public static JsonProperty GetJsonProperty<T>(T obj, string jsonName, bool exact = false, 
        IContractResolver? resolver = null)
    {
        ArgumentNullException.ThrowIfNull(obj);

        resolver ??= defaultResolver;
        var objType = typeof(T);

        if (resolver.ResolveContract(objType) is not JsonObjectContract contract)
            throw new ArgumentException($"{objType} is not serialized as a JSON object");

        var property = contract.Properties.GetProperty(jsonName, exact 
            ? StringComparison.Ordinal 
            : StringComparison.OrdinalIgnoreCase);

        if (property == null)
            throw new ArgumentException($"Property {jsonName} was not found.");

        return property;
    }
}

With the IContractResolver we pass as resolver as a parameter, we get the contract definition of our obj instance. If there is no resolver passed on, we take the default resolver implementation from _defaultResolver which we fill from the JsonSerializer class via the CreateDefault() method. After performing various checks, it retrieves the JsonProperty based on the specified property name while also considering case sensitivity as determined by the exact parameter via the contract we resolved. 

Let’s see it in action:

var sales = new Sales
{
    YearlySales = "365000",
    DailySales = "1000"
};

JsonProperty salesPerYearProperty = ResolverHelper.GetJsonProperty(sales, "Slx_per_Year");
JsonProperty salesPerDayProperty = ResolverHelper.GetJsonProperty(sales, "Slx_per_DAY");

Console.WriteLine($"{salesPerYearProperty.PropertyName}");
Console.WriteLine($"{salesPerDayProperty.PropertyName}");

The output of this for our sales object will be:

Slx_PER_Year
Slx_PER_DAY

Retrieve JSON Property Names Using System.Text.Json With Reflection

We can also use System.Text.Json to retrieve JSON properties. This library uses the JsonPropertyName attribute to specify the property name:

public class Sales
{
    [JsonPropertyName("Slx_PER_Year")]
    public string? YearlySales { get; set; }

    [JsonPropertyName("Slx_PER_DAY")]
    public string? DailySales { get; set; }
}

We are extracting properties using Reflection and LINQ:

public static string[] GetJsonPropertyNames(object obj)
{
    Type type = obj.GetType();
    PropertyInfo[] properties = type.GetProperties();
    string[] propertyNames = properties
        .Select(property =>
            property.GetCustomAttribute<JsonPropertyNameAttribute>()?.Name ?? property.Name)
        .ToArray();

    return propertyNames;
}

The GetProperties() function retrieves all property names in an array. Then, using the LINQ Select(), we iterate over each of the properties, checking for the the JsonPropertyNameAttribute. If the attribute is found, we return its value as the property name, otherwise we return the default property name.

Let’s see it in action:

var sales = new Sales 
{ 
    YearlySales = "365000", 
    DailySales = "1000" 
};

var propertyNames = JsonTextImplementation.GetJsonPropertyNames(sales);

Console.WriteLine("JSON property names:");
foreach (var propertyName in propertyNames)
{
    Console.WriteLine(propertyName);
}

Here we retrieve the property names of our sales object similar to what we did in the previously mentioned approaches and print it out to the console:

JSON property names:
Slx_PER_Year
Slx_PER_DAY

Conclusion

In this article, we explored different libraries and approaches in C# for retrieving JSON properties, showcasing how they help us customize JSON data to meet our specific requirements.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!