/// <summary> /// Gets the context URI for the specified ODataPayloadElement. /// </summary> /// <param name="payloadElement">The annotated payload element to get the context URI for.</param> /// <returns>The context URI from the annotated payload element or null if no context URI annotation exists.</returns> /// <remarks>If not context URI annotation is found on the <paramref name="payloadElement"/>, this /// method will try to compute the context URI from the expected type annotation. If successful, /// it will cache the computed context URI as annotation on the payload element.</remarks> public static string ContextUri(this ODataPayloadElement payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); JsonLightContextUriAnnotation contextUriAnnotation = (JsonLightContextUriAnnotation)payloadElement.GetAnnotation(typeof(JsonLightContextUriAnnotation)); string contextUri = null; bool cacheContextUri = false; // If an explicit context URI exists, return it if (contextUriAnnotation != null) { contextUri = contextUriAnnotation.ContextUri; } else { // Otherwise construct a context URI from the expected type annotation ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation = (ExpectedTypeODataPayloadElementAnnotation)payloadElement.GetAnnotation(typeof(ExpectedTypeODataPayloadElementAnnotation)); if (expectedTypeAnnotation != null) { // Construct a context URI from the exptected type annotation JsonLightMetadataDocumentUriAnnotation metadataDocumentUriAnnotation = (JsonLightMetadataDocumentUriAnnotation)payloadElement.GetAnnotation(typeof(JsonLightMetadataDocumentUriAnnotation)); string metadataDocumentUri = metadataDocumentUriAnnotation == null ? JsonLightConstants.DefaultMetadataDocumentUri.AbsoluteUri : metadataDocumentUriAnnotation.MetadataDocumentUri; string projectionString = null; JsonLightContextUriProjectionAnnotation contextUriProjectionAnnotation = (JsonLightContextUriProjectionAnnotation)payloadElement.GetAnnotation(typeof(JsonLightContextUriProjectionAnnotation)); if (contextUriProjectionAnnotation != null) { // If we have a context URI projection, apply it to the context URI if the context URI does not already have one. projectionString = contextUriProjectionAnnotation.ContextUriProjection; Regex contextUriSelectExpandPattern = new Regex(@"(?:(?<!#Collection))\(.*\)"); // A 'null' projection string means that all properties should be projected. if (projectionString != null) { bool hasProjection = contextUriSelectExpandPattern.IsMatch(projectionString); if (!hasProjection) { // Inject the projection string into the context URI projectionString = JsonLightConstants.ContextUriProjectionStart + projectionString + JsonLightConstants.ContextUriProjectionEnd; } } } contextUri = BuildContextUri(payloadElement.ElementType, metadataDocumentUri, expectedTypeAnnotation, projectionString); cacheContextUri = true; } } // Cache the computed context URI on the payload element (non-comparable annotation) if (cacheContextUri) { payloadElement.WithContextUri(contextUri); payloadElement.RemoveAnnotations(typeof(JsonLightContextUriProjectionAnnotation)); } return(contextUri); }