internal static IncludePathNode GenerateIncludeTree(JsonApiResource apiResource, string path) { if (string.IsNullOrWhiteSpace(path)) { return(null); } var subPaths = path.Split(new[] { '.' }, 2); var relationshipName = subPaths[0].ToJsonRelationshipName(); var relationshipResource = apiResource.Relationships.FirstOrDefault(x => x.Name == relationshipName); if (relationshipResource == null) { throw new Exception($"Cannot include resource {path}: Path does not exist."); } var resultNode = new IncludePathNode { PropertyPath = relationshipName, IncludeApiResourceRelationship = relationshipResource, Child = subPaths.Length > 1 ? GenerateIncludeTree(relationshipResource.RelatedResource, subPaths[1]) : null }; return(resultNode); }
private static void ProcessIncludeTree(IJsonApiDocument document, IncludePathNode includePathTree, object data, string baseUrl) { var relationship = includePathTree.IncludeApiResourceRelationship; var dataType = data.GetType(); var propertyInfo = dataType.GetProperty(relationship.PropertyName); if (propertyInfo == null) { throw new Exception($"Property {relationship.PropertyName} does not exist for type {dataType.Name}."); } var value = propertyInfo.GetValueFast(data); if (value == null) { return; } if (relationship.Kind == RelationshipKind.BelongsTo) { var jsonResourceObject = new JsonApiResourceObject(); jsonResourceObject.FromApiResource(value, relationship.RelatedResource, baseUrl); if (document.Included == null) { document.Included = new JsonApi.Dictionaries.JsonApiResourceObjectDictionary(); } document.Included.AddResource(jsonResourceObject); if (includePathTree.Child != null) { // jump down the rabbit hole ProcessIncludeTree(document, includePathTree.Child, value, baseUrl); } } else { if (value is IEnumerable <object> collection && collection.Any()) { if (document.Included == null) { document.Included = new JsonApi.Dictionaries.JsonApiResourceObjectDictionary(); } foreach (var item in collection) { if (item == null) { continue; } var jsonResourceObject = new JsonApiResourceObject(); jsonResourceObject.FromApiResource(item, relationship.RelatedResource, baseUrl); document.Included.AddResource(jsonResourceObject); if (includePathTree.Child != null) { // jump down the rabbit hole ProcessIncludeTree(document, includePathTree.Child, item, baseUrl); } } } } }