Sometimes, you have to deal with importing big data files and the data is not really what you’ve expected. Here is a solution for handling Deserializing data with a nested property (array). You may need to add a Depth parameter if propertyName is not enough to identify the field to deserialize.
Of course, the method use yield in order to not allocate any memory, very handy for big files !
Enjoy 🙂
/// <summary>
/// Deserialize nested array property as IEnumerable
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream">Stream</param>
/// <param name="propertyName">nested property to deserialize</param>
/// <param name="settings">JSON.net setting</param>
/// <returns>Enumerable of T</returns>
public static IEnumerable<T> DeserializeEnumerableNestedProperty<T>(Stream stream, string propertyName, JsonSerializerSettings settings = default)
{
using StreamReader sr = new StreamReader(stream, leaveOpen: true);
using JsonTextReader reader = new JsonTextReader(sr);
// looking for property
while (reader.Read())
{
if (reader.TokenType != JsonToken.PropertyName)
{
continue;
}
var currentPropertyName = reader.Value as string;
if (currentPropertyName?.Equals(propertyName, StringComparison.OrdinalIgnoreCase) != true)
{
continue;
}
break;
}
// deserialize Array as enumerable
while (reader.Read())
{
if (reader.TokenType != JsonToken.StartArray)
{
continue;
}
var serializer = Newtonsoft.Json.JsonSerializer.CreateDefault(settings);
while (reader.Read() && reader.TokenType == JsonToken.StartObject)
{
T obj = serializer.Deserialize<T>(reader)!;
yield return obj;
}
break;
}
}