Example #1
0
        private void ReadFlattenedJsonIntoObject(object finalResult, IDictionary <string, object> flattenedJson)
        {
            Type objectType = finalResult.GetType();
            JsonClassAttribute jsonClassAttribute = objectType.GetCustomAttribute <JsonClassAttribute>();

            PropertyInfo[] propertiesToDeserialize = objectType.GetProperties();
            foreach (PropertyInfo propToDeserialize in propertiesToDeserialize)
            {
                JsonPropertyAttribute jsonPropertyAttribute = propToDeserialize.GetCustomAttribute <JsonPropertyAttribute>(true);
                string flatJsonLookupKey;
                bool   isJsonPropertyAttributeValueASelector;

                if (jsonPropertyAttribute != null)
                {
                    isJsonPropertyAttributeValueASelector = jsonPropertyAttribute.PropertyName.Split(',').Any(y => y == "{}" || y == "[]");
                    flatJsonLookupKey = this.PascalizePath(jsonPropertyAttribute.PropertyName);
                }
                else
                {
                    isJsonPropertyAttributeValueASelector = false;
                    flatJsonLookupKey = propToDeserialize.Name.Pascalize();
                }

                if (jsonClassAttribute?.IsEnumerablePath == false)
                {
                    flatJsonLookupKey = $"{this.PascalizePath(jsonClassAttribute.Path)}.{flatJsonLookupKey}";
                }

                string flatJsonLookupKeyParent;

                if (isJsonPropertyAttributeValueASelector)
                {
                    flatJsonLookupKeyParent = this.GetFirstFlatKeyThatMatchesSelector(flatJsonLookupKey, flattenedJson);
                }
                else
                {
                    flatJsonLookupKeyParent = this.GetFlatKeyParent(flatJsonLookupKey);
                }

                Type propertyTypeUnderlying = Nullable.GetUnderlyingType(propToDeserialize.PropertyType) ?? propToDeserialize.PropertyType;

                if (Type.GetTypeCode(propertyTypeUnderlying) == TypeCode.Object)
                {
                    // Get get all the props for that object
                    Dictionary <string, object> propsForDeserializingObject = flattenedJson
                                                                              .Where(y => y.Key.StartsWith($"{flatJsonLookupKeyParent}.") || y.Key.StartsWith($"{flatJsonLookupKeyParent}["))
                                                                              .ToDictionary(
                        // and then trim the parent from the dictionary
                        keySelector: y => {
                        string newKey = y.Key.Substring(flatJsonLookupKeyParent.Length);

                        if (newKey.StartsWith("."))
                        {
                            newKey = newKey.Substring(1);
                        }

                        return(newKey);
                    },
                        elementSelector: y => y.Value);

                    object result = this.ReadFlattenedJsonIntoTargetObjectType(propsForDeserializingObject, propToDeserialize.PropertyType);

                    propToDeserialize.SetValue(finalResult, result);
                }
                else
                {
                    if (!flattenedJson.TryGetValue(flatJsonLookupKey, out object flatJsonLookupValue))
                    {
                        if (jsonPropertyAttribute == null)
                        {
                            continue;
                        }

                        if (flattenedJson.TryGetValue(flatJsonLookupKeyParent, out object flatJsonLookupKeyParentObject))
                        {
                            // If the key exists, but the value is null, it's ok, don't throw any error.
                            if (flatJsonLookupKeyParentObject == null)
                            {
                                continue;
                            }
                        }

                        continue;
                    }

                    if (flatJsonLookupValue != null)
                    {
                        Type underlyingPropertyType = Nullable.GetUnderlyingType(propToDeserialize.PropertyType);

                        flatJsonLookupValue = Convert.ChangeType(flatJsonLookupValue, underlyingPropertyType ?? propToDeserialize.PropertyType);
                    }


                    propToDeserialize.SetValue(finalResult, flatJsonLookupValue);
                }
            }
        }
Example #2
0
        private void ReadFlattenedJsonIntoList(IList finalList, IDictionary <string, object> flattenedJson)
        {
            Type objectType = finalList.GetType();
            JsonClassAttribute jsonClassAttribute = objectType.GetCustomAttribute <JsonClassAttribute>();

            Type underlyingEnumerableType = objectType
                                            .GetInterfaces()
                                            .FirstOrDefault(y => typeof(IEnumerable <object>).IsAssignableFrom(y))
                                            .GetGenericArguments()
                                            .FirstOrDefault();

            if (jsonClassAttribute == null)
            {
                jsonClassAttribute = underlyingEnumerableType.GetCustomAttribute <JsonClassAttribute>();
            }

            string jsonClassAttributePath = jsonClassAttribute?.Path ?? "";

            jsonClassAttributePath = this.PascalizePath(jsonClassAttributePath);

            // Key all the keys which start with the JsonClassAttribute's path
            // And group them by the array index
            var groupedFlattenJsonByArrayIndex = flattenedJson

                                                 // Must start with an array square bracket
                                                 .Where(y => y.Key.StartsWith($"{jsonClassAttributePath}"))

                                                 .GroupBy(y =>
            {
                int indexOfArray = y.Key.IndexOf("[");

                if (indexOfArray == -1)
                {
                    return("");
                }

                // The array is part of a nested object, not the direct object
                if (y.Key.IndexOf(".") < indexOfArray)
                {
                    return("");
                }

                string pathToArray = y.Key.Substring(0, indexOfArray);

                if (!pathToArray.EndsWith(jsonClassAttributePath))
                {
                    return("");
                }

                string index = y.Key.Substring(indexOfArray + 1);
                index        = index.Substring(0, index.IndexOf("]"));

                return(index);
            });

            foreach (var group in groupedFlattenJsonByArrayIndex)
            {
                Dictionary <string, object> arrayItemDictionary;

                if (!String.IsNullOrEmpty(group.Key))
                {
                    arrayItemDictionary = group.ToDictionary(
                        keySelector: y =>
                    {
                        string newKey = y.Key.Substring(y.Key.IndexOf("]") + 1);

                        if (newKey.StartsWith("."))
                        {
                            newKey = newKey.Substring(1);
                        }

                        return(newKey);
                    },
                        elementSelector: pair => pair.Value);
                }
                else
                {
                    arrayItemDictionary = group.ToDictionary(y => y.Key, y => y.Value);
                }

                object targetObjectResult = this.ReadFlattenedJsonIntoTargetObjectType(arrayItemDictionary, underlyingEnumerableType);

                finalList.Add(targetObjectResult);
            }
        }