/// <summary> /// Tries to handle the current segment as a key property value. /// </summary> /// <param name="segmentText">The segment text.</param> /// <param name="previous">The previous segment.</param> /// <param name="previousKeySegment">The parent node's key segment.</param> /// <param name="urlConvention">The current url convention for the server.</param> /// <param name="keySegment">The key segment that was created if the segment could be interpreted as a key.</param> /// <param name="enableUriTemplateParsing">Whether Uri template parsing is enabled.</param> /// <param name="resolver">The resolver to use.</param> /// <returns>Whether or not the segment was interpreted as a key.</returns> internal static bool TryHandleSegmentAsKey(string segmentText, ODataPathSegment previous, KeySegment previousKeySegment, UrlConvention urlConvention, out KeySegment keySegment, bool enableUriTemplateParsing = false, ODataUriResolver resolver = null) { Debug.Assert(previous != null, "previous != null"); Debug.Assert(urlConvention != null, "urlConvention != null"); if (resolver == null) { resolver = ODataUriResolver.Default; } keySegment = null; // If the current convention is not keys-as-segments, then this does not apply. if (!urlConvention.GenerateKeyAsSegment) { return(false); } // Keys only apply to collections, so if the prior segment is already a singleton, do not treat this segment as a key. if (previous.SingleResult) { return(false); } // System segments (ie '$count') are never keys. if (IsSystemSegment(segmentText)) { return(false); } // If the previous type is not an entity collection type // TODO: collapse this and SingleResult. IEdmEntityType targetEntityType; if (previous.TargetEdmType == null || !previous.TargetEdmType.IsEntityOrEntityCollectionType(out targetEntityType)) { return(false); } // If the resource type has more than 1 key property, then do not treat the segment as a key. var keyProperties = targetEntityType.Key().ToList(); if (keyProperties.Count > 1) { return(false); } // At this point it must be treated as a key, so fail if it is malformed. Debug.Assert(keyProperties.Count == 1, "keyProperties.Count == 1"); keySegment = CreateKeySegment(previous, previousKeySegment, SegmentArgumentParser.FromSegment(segmentText, enableUriTemplateParsing), resolver); return(true); }
/// <summary> /// Tries to handle the current segment as a key property value. /// </summary> /// <param name="segmentText">The segment text.</param> /// <param name="previous">The previous segment.</param> /// <param name="previousKeySegment">The parent node's key segment.</param> /// <param name="urlConvention">The current url convention for the server.</param> /// <param name="keySegment">The key segment that was created if the segment could be interpreted as a key.</param> /// <param name="enableUriTemplateParsing">Whether Uri template parsing is enabled.</param> /// <param name="resolver">The resolver to use.</param> /// <returns>Whether or not the segment was interpreted as a key.</returns> internal static bool TryHandleSegmentAsKey(string segmentText, ODataPathSegment previous, KeySegment previousKeySegment, UrlConvention urlConvention, out KeySegment keySegment, bool enableUriTemplateParsing = false, ODataUriResolver resolver = null) { Debug.Assert(previous != null, "previous != null"); Debug.Assert(urlConvention != null, "urlConvention != null"); if (resolver == null) { resolver = ODataUriResolver.Default; } keySegment = null; // If the current convention does not support keys-as-segments, then this does not apply. if (!(urlConvention.GenerateKeyAsSegment || urlConvention.ODataSimplified)) { return(false); } // Keys only apply to collections, so if the prior segment is already a singleton, do not treat this segment as a key. if (previous.SingleResult) { return(false); } // System segments (ie '$count') are never keys. if (IsSystemSegment(segmentText)) { return(false); } // If the previous type is not an entity collection type // TODO: collapse this and SingleResult. IEdmEntityType targetEntityType; if (previous.TargetEdmType == null || !previous.TargetEdmType.IsEntityOrEntityCollectionType(out targetEntityType)) { return(false); } // Previously KeyAsSegment only allows single key, but we can also leverage related key finder to auto fill // missed key value from referential constraint information, which would be done in CreateKeySegment. // CreateKeySegment method will check whether key properties are missing after taking in related key values. keySegment = CreateKeySegment(previous, previousKeySegment, SegmentArgumentParser.FromSegment(segmentText, enableUriTemplateParsing), resolver); return(true); }