public IEnumerable <T> GetItemsFromSerializationText <T>(string json, JsonSerializationSettings settings) where T : class, new() { if (settings == null) { settings = new JsonSerializationSettings(); } switch (settings.SerializationType) { case SerializationType.Array: { var setArray = JArray.Parse(json); foreach (var i in setArray.Children()) { if (i.Type == JTokenType.Object) { yield return(CEF.Deserialize <T>(i.ToString())); } } break; } case SerializationType.ObjectWithSchemaType1AndRows: { // Read schema Dictionary <string, Type> schema = new Dictionary <string, Type>(); var root = JObject.Parse(json); // Read schema foreach (var propInfo in root.GetValue(settings.SchemaName).ToArray()) { if (propInfo is JObject jo) { if (jo.Count < 2 || jo.Count > 3) { throw new CEFInvalidOperationException("Invalid JSON format."); } JProperty pn = (from a in jo.Children() let b = a as JProperty where b != null && b.Name.Equals(settings.SchemaFieldNameName) select b).FirstOrDefault(); JProperty pt = (from a in jo.Children() let b = a as JProperty where b != null && b.Name.Equals(settings.SchemaFieldTypeName) select b).FirstOrDefault(); JProperty pr = (from a in jo.Children() let b = a as JProperty where b != null && b.Name.Equals(settings.SchemaFieldRequiredName) select b).FirstOrDefault(); if (pn == null || pt == null) { throw new CEFInvalidOperationException("Invalid JSON format."); } var t = settings.GetDataType(pt.Value.ToString()); var torig = t; // Assume that any property might be omitted/missing which means everything should be considered nullable if (t.IsValueType && !(t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>))) { t = typeof(Nullable <>).MakeGenericType(t); } var name = pn.Value.ToString(); schema[name] = t; // If is required, we add a validation for this if (pr != null && bool.TryParse(pr.Value.ToString(), out bool prv) && prv) { ValidationService.RegisterRequired <T>(torig, name); } } } // Read objects, using the schema as the "basis" where missing/omitted properties are still carried through foreach (var itemInfo in root.GetValue(settings.DataRootName).ToArray()) { var obj = CEF.Deserialize <T>(itemInfo.ToString()); var iw = obj.AsInfraWrapped(); // We need to apply property type settings after-the-fact var allProp = iw.GetAllValues(); foreach (var propInfo in schema) { var existingInfo = (from a in allProp where a.Key == propInfo.Key select(propInfo.Value, a.Value)); if (existingInfo.Any()) { iw.SetValue(propInfo.Key, existingInfo.First().Item2, existingInfo.First().Item1); } else { iw.SetValue(propInfo.Key, null, propInfo.Value); } } yield return(obj); } break; } } }