/// <summary>
        /// Find out whether to expect action descriptor with projection in request uri
        /// </summary>
        /// <param name="requestUri">The request uri</param>
        /// <param name="action">The action</param>
        /// <param name="isTopLevelElement">Whether the entity being verified is top level payload element</param>
        /// <returns>Whether to expect action descriptor</returns>
        private bool ExpectActionWithProjection(ODataUri requestUri, Function action, bool isTopLevelElement)
        {
            ODataUriSegmentPathCollection selectSegments = requestUri.SelectSegments;
            ODataUriSegmentPathCollection expandSegments = requestUri.ExpandSegments;

            // handle single level $select path, expect action descriptor if $select=ActionName or $select=Container.*
            foreach (var selectSegmentPath in selectSegments.Where(ss => ss.Count == 1))
            {
                ODataUriSegment selectSegment = selectSegmentPath.Single();

                if (isTopLevelElement && this.FuctionMatchWithSelectFunctionSegment(action, selectSegment))
                {
                    return(true);
                }

                if (this.IsSelectAllFunctionSegment(selectSegment))
                {
                    return(true);
                }
            }

            // handle multiple level $select path, expect action descriptor for $expand=Rating if: $select=Rating or $select=Rating/ActionName or $Select=Rating/Container.*
            foreach (var expandSegmentPath in expandSegments)
            {
                List <ODataUriSegment> expandSegmentList = expandSegmentPath.ToList();
                foreach (var selectSegmentPath in selectSegments.Where(ss => ss.Count == expandSegmentPath.Count || ss.Count == expandSegmentPath.Count + 1))
                {
                    List <ODataUriSegment> selectSegmentList = selectSegmentPath.ToList();
                    if (this.FunctionMatchWithExpandSegmentList(selectSegmentList, expandSegmentList, action))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #2
0
        /// <summary>
        /// Parses a collection of segment paths using the format expected for the '$expand' and '$select' query options
        /// </summary>
        /// <param name="type">The entity type the paths start from</param>
        /// <param name="toParse">The string to parse</param>
        /// <returns>The parsed collection of segment paths</returns>
        public static ODataUriSegmentPathCollection ParseSegmentPathCollection(EntityType type, string toParse)
        {
            ExceptionUtilities.CheckArgumentNotNull(toParse, "toParse");

            ODataUriSegmentPathCollection segmentPathCollection = new ODataUriSegmentPathCollection();
            foreach (string path in toParse.Trim().Split(','))
            {
                IList<ODataUriSegment> segmentPath = new List<ODataUriSegment>();

                IEnumerable<MemberProperty> possibleProperties = type.AllProperties;
                IEnumerable<NavigationProperty> possibleNavigations = type.AllNavigationProperties;

                foreach (string segment in path.Trim().Split('/'))
                {
                    EntityType matchingType;
                    if (TryGetEntityTypeInHierarchy(type, segment, out matchingType))
                    {
                        segmentPath.Add(new EntityTypeSegment(matchingType));
                        continue;
                    }

                    MemberProperty property = null;
                    if (possibleProperties != null)
                    {
                        property = possibleProperties.SingleOrDefault(p => p.Name == segment);
                    }

                    NavigationProperty navigation = null;
                    if (possibleNavigations != null)
                    {
                        navigation = possibleNavigations.SingleOrDefault(p => p.Name == segment);
                    }

                    if (property == null && navigation == null)
                    {
                        possibleProperties = null;
                        SystemSegment systemSegment;
                        if (SystemSegment.TryGet(segment, out systemSegment))
                        {
                            segmentPath.Add(systemSegment);
                        }
                        else
                        {
                            segmentPath.Add(new UnrecognizedSegment(segment));
                        }
                    }
                    else if (property != null)
                    {
                        possibleNavigations = null;

                        ComplexDataType complexType = property.PropertyType as ComplexDataType;
                        if (complexType != null)
                        {
                            possibleProperties = complexType.Definition.Properties;
                        }
                        else
                        {
                            possibleProperties = null;
                            possibleNavigations = null;
                        }

                        segmentPath.Add(new PropertySegment(property));
                    }
                    else
                    {
                        possibleProperties = navigation.ToAssociationEnd.EntityType.AllProperties;
                        possibleNavigations = navigation.ToAssociationEnd.EntityType.AllNavigationProperties;
                        segmentPath.Add(new NavigationSegment(navigation));
                    }
                }

                segmentPathCollection.Add(segmentPath);
            }

            return segmentPathCollection;
        }