/// <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); }
/// <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; }