/// <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="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> /// <returns>Whether or not the segment was interpreted as a key.</returns> internal static bool TryHandleSegmentAsKey(string segmentText, IPathSegment previous, UrlConvention urlConvention, out IPathSegment keySegment) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(previous != null, "previous != null"); Debug.Assert(urlConvention != null, "urlConvention != null"); keySegment = null; // If the current convention is not keys-as-segments, then this does not apply. if (!urlConvention.GenerateKeyAsSegment) { return(false); } // If the current identifier was preceeded by a '$' segment, then do not treat it as a key. if (previous.IsEscapeMarker) { 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, KeyInstance.FromSegment(segmentText)); return(true); }