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
.
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
.
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.