Пример #1
0
        /// <summary>
        /// By default, the server serializer exposes all defined relationships, unless
        /// in the <see cref="ResourceDefinition{T}"/> a subset to hide was defined explicitly.
        /// </summary>
        /// <param name="resourceType">Type of entity to be serialized</param>
        /// <returns>List of allowed relationships in the serialized result</returns>
        private List <RelationshipAttribute> GetRelationshipsToSerialize(Type resourceType)
        {
            // Check the relationships cache to see if the allowed attrs for this resource type were determined before.
            if (_relationshipsToSerializeCache.TryGetValue(resourceType, out List <RelationshipAttribute> allowedRelations))
            {
                return(allowedRelations);
            }

            // Get the list of relationships to be exposed for this type
            allowedRelations = _fieldsToSerialize.GetAllowedRelationships(resourceType);
            // add to cache so we we don't have to look this up next time.
            _relationshipsToSerializeCache.Add(resourceType, allowedRelations);
            return(allowedRelations);
        }
Пример #2
0
        /// <summary>
        /// Applies include queries
        /// </summary>
        protected virtual IQueryable <TResource> ApplyInclude(IQueryable <TResource> entities, RelationshipAttribute chainPrefix = null)
        {
            var type             = entities.ElementType;
            var allowedRelations = _fieldsToSerialize.GetAllowedRelationships(type);
            var chains           = _includeService.Get();
            var fakeChains       = chains.ToList();

            // sven
            // loop through and only add missing ones
            foreach (var relation in allowedRelations)
            {
                // add each allowedRelation to single list because then they get treated separately.
                // otherwise it would get treated as a follow-up relation
                bool isIncluded = fakeChains.Select(x => x.First()).Any(x => x.Equals(relation));
                if (!isIncluded)
                {
                    var subList = new List <RelationshipAttribute> {
                        relation
                    };
                    //var relationType = relation.RightType;
                    //var subAllowed = _fieldsToSerialize.GetAllowedRelationships(relationType);

                    //subList.AddRange(subAllowed);
                    fakeChains.Add(subList);
                }
            }

            if (chainPrefix != null)
            {
                chains.Add(new List <RelationshipAttribute>());
            }

            // sven
            foreach (var inclusionChain in fakeChains)
            {
                if (chainPrefix != null)
                {
                    inclusionChain.Insert(0, chainPrefix);
                }

                entities = _repository.Include(entities, inclusionChain);
            }

            return(entities);
        }
        /// <summary>
        /// Gets the resource object for <paramref name="parent"/> by searching the included list.
        /// If it was not already build, it is constructed and added to the included list.
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="relationship"></param>
        /// <returns></returns>
        private ResourceObject GetOrBuildResourceObject(IIdentifiable parent, RelationshipAttribute relationship)
        {
            var type         = parent.GetType();
            var resourceName = _provider.GetResourceContext(type).ResourceName;
            var entry        = _included.SingleOrDefault(ro => ro.Type == resourceName && ro.Id == parent.StringId);

            if (entry == null)
            {
                entry = Build(parent, _fieldsToSerialize.GetAllowedAttributes(type, relationship), _fieldsToSerialize.GetAllowedRelationships(type));
                _included.Add(entry);
            }
            return(entry);
        }
        /// <summary>
        /// Builds the values of the relationships object on a resource object.
        /// The server serializer only populates the "data" member when the relationship is included,
        /// and adds links unless these are turned off. This means that if a relationship is not included
        /// and links are turned off, the entry would be completely empty, ie { }, which is not conform
        /// json:api spec. In that case we return null which will omit the entry from the output.
        /// </summary>
        protected override RelationshipEntry GetRelationshipData(RelationshipAttribute relationship, IIdentifiable entity)
        {
            RelationshipEntry relationshipEntry = null;
            List <List <RelationshipAttribute> > relationshipChains = null;

            relationshipEntry = base.GetRelationshipData(relationship, entity);

            // sven
            if (Equals(relationship, _requestRelationship) || ShouldInclude(relationship, out relationshipChains) || true)
            {
                if (relationshipChains != null && relationshipChains.Count != 0 && relationshipEntry.HasResource)
                {
                    // sven
                    //if (relationshipChains.Count == 0) {
                    //    relationshipChains = _fieldsToSerialize.GetAllowedRelationships(relationship.RightType)
                    //        .Select(x => new List<RelationshipAttribute> { x }).ToList();
                    //}

                    // every chain in relationshipChains has the same on first position = the relationship requested
                    var allowedRelations = _fieldsToSerialize.GetAllowedRelationships(relationship.RightType);
                    //var fakeChains = relationshipChains.ToList();
                    var fakeChains = new List <List <RelationshipAttribute> >();

                    var singleOneIndex = fakeChains.FindIndex(x => x.Count == 1 && x.First().Equals(relationship));
                    if (singleOneIndex != -1)
                    {
                        fakeChains.RemoveAt(singleOneIndex);
                    }

                    foreach (var relation in allowedRelations)
                    {
                        bool isIncluded = fakeChains.Any(x => x.Last().Equals(relation));
                        if (!isIncluded)
                        {
                            var subList = new List <RelationshipAttribute> {
                                relationship, relation
                            };
                            fakeChains.Add(subList);
                        }
                    }

                    // sven
                    foreach (var chain in fakeChains)
                    {
                        // traverses (recursively) and extracts all (nested) related entities for the current inclusion chain.
                        _includedBuilder.IncludeRelationshipChain(chain, entity);
                    }
                }
            }

            var links = _linkBuilder.GetRelationshipLinks(relationship, entity);

            // sven
            // omit links everytime
            //if (links != null)
            //    // if links relationshipLinks should be built for this entry, populate the "links" field.
            //    (relationshipEntry ??= new RelationshipEntry()).Links = links;

            // if neither "links" nor "data" was populated, return null, which will omit this entry from the output.
            // (see the NullValueHandling settings on <see cref="ResourceObject"/>)
            return(relationshipEntry);
        }