コード例 #1
0
        internal static IEdmNavigationProperty ValidateNestedResourceInfo(
            ODataNestedResourceInfo nestedResourceInfo,
            IEdmStructuredType declaringStructuredType,
            ODataPayloadKind?expandedPayloadKind,
            bool throwOnUndeclaredProperty)
        {
            Debug.Assert(nestedResourceInfo != null, "nestedResourceInfo != null");
            Debug.Assert(
                !expandedPayloadKind.HasValue ||
                expandedPayloadKind.Value == ODataPayloadKind.EntityReferenceLink ||
                expandedPayloadKind.Value == ODataPayloadKind.Resource ||
                expandedPayloadKind.Value == ODataPayloadKind.ResourceSet,
                "If an expanded payload kind is specified it must be resource, resource set or entity reference link.");

            // Navigation link must have a non-empty name
            if (string.IsNullOrEmpty(nestedResourceInfo.Name))
            {
                throw new ODataException(Strings.ValidationUtils_LinkMustSpecifyName);
            }

            // If we write an entity reference link, don't validate the multiplicity of the IsCollection
            // property if it is 'false' (since we allow writing a singleton navigation link for
            // a collection navigation property in requests) nor the consistency of payload kind and metadata
            // (which is done separately in ODataWriterCore.CheckForNestedResourceInfoWithContent).
            bool isEntityReferenceLinkPayload = expandedPayloadKind == ODataPayloadKind.EntityReferenceLink;

            // true only if the expandedPayloadKind has a value and the value is 'Resource Set'
            bool isResourceSetPayload = expandedPayloadKind == ODataPayloadKind.ResourceSet;

            // Make sure the IsCollection property agrees with the payload kind for resource and resource set payloads
            Func <object, string> errorTemplate = null;

            if (!isEntityReferenceLinkPayload && nestedResourceInfo.IsCollection.HasValue && expandedPayloadKind.HasValue)
            {
                // For resource set/resource make sure the IsCollection property is set correctly.
                if (isResourceSetPayload != nestedResourceInfo.IsCollection.Value)
                {
                    errorTemplate = expandedPayloadKind.Value == ODataPayloadKind.ResourceSet
                        ? (Func <object, string>)Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithResourceSetContent
                        : Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithResourceContent;
                }
            }

            IEdmNavigationProperty navigationProperty = null;

            if (errorTemplate == null && declaringStructuredType != null)
            {
                navigationProperty = ValidateNavigationPropertyDefined(nestedResourceInfo.Name, declaringStructuredType, throwOnUndeclaredProperty);
                if (navigationProperty != null)
                {
                    bool isCollectionType = navigationProperty.Type.TypeKind() == EdmTypeKind.Collection;

                    // Make sure the IsCollection property agrees with the metadata type for resource and resource set payloads
                    if (nestedResourceInfo.IsCollection.HasValue && isCollectionType != nestedResourceInfo.IsCollection)
                    {
                        // Ignore the case where IsCollection is 'false' and we are writing an entity reference link
                        // (see comment above)
                        if (!(nestedResourceInfo.IsCollection == false && isEntityReferenceLinkPayload))
                        {
                            errorTemplate = isCollectionType
                                ? (Func <object, string>)Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithResourceSetMetadata
                                : Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithResourceMetadata;
                        }
                    }

                    // Make sure that the payload kind agrees with the metadata.
                    // For entity reference links we check separately in ODataWriterCore.CheckForNestedResourceInfoWithContent.
                    if (!isEntityReferenceLinkPayload && expandedPayloadKind.HasValue && isCollectionType != isResourceSetPayload)
                    {
                        errorTemplate = isCollectionType
                            ? (Func <object, string>)Strings.WriterValidationUtils_ExpandedLinkWithResourcePayloadAndResourceSetMetadata
                            : Strings.WriterValidationUtils_ExpandedLinkWithResourceSetPayloadAndResourceMetadata;
                    }
                }
            }

            if (errorTemplate != null)
            {
                string uri = nestedResourceInfo.Url == null ? "null" : UriUtils.UriToString(nestedResourceInfo.Url);
                throw new ODataException(errorTemplate(uri));
            }

            return(navigationProperty);
        }
コード例 #2
0
        /// <summary>
        /// Validates that message writer settings are correct.
        /// </summary>
        /// <param name="messageWriterSettings">The message writer settings to validate.</param>
        /// <param name="writingResponse">True if we are writing a response.</param>
        internal static void ValidateMessageWriterSettings(ODataMessageWriterSettings messageWriterSettings, bool writingResponse)
        {
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            if (messageWriterSettings.BaseUri != null && !messageWriterSettings.BaseUri.IsAbsoluteUri)
            {
                throw new ODataException(Strings.WriterValidationUtils_MessageWriterSettingsBaseUriMustBeNullOrAbsolute(UriUtils.UriToString(messageWriterSettings.BaseUri)));
            }

            if (messageWriterSettings.HasJsonPaddingFunction() && !writingResponse)
            {
                throw new ODataException(Strings.WriterValidationUtils_MessageWriterSettingsJsonPaddingOnRequestMessage);
            }
        }
コード例 #3
0
        /// <summary>
        /// Validates that the uri's reference of $requestId, if used, is one of the depends-on requests.
        /// The Uri can be either absolute or relative.
        /// Exception is thrown if the request Id reference is not found in the list of depends-on requests.
        /// </summary>
        /// <param name="uri">The Uri to validate the request Id reference.</param>
        /// <param name="dependsOnRequestIds">Enumeration of request Ids used to lookup the request Id reference.</param>
        /// <param name="baseUri">The baseUri used for validation.</param>
        internal static void ValidateReferenceUri(Uri uri, IEnumerable <string> dependsOnRequestIds, Uri baseUri)
        {
            Debug.Assert(uri != null, "uri != null");

            if (UriUtils.UriToString(uri).IndexOf('$') == -1)
            {
                // uri does not use $requestId,
                return;
            }

            string relativePath = null;

            if (uri.IsAbsoluteUri)
            {
                if (baseUri == null)
                {
                    // The absolute Uri can contain $ character followed by name of system resource
                    // such as $all, $metadata, etc, along with an unspecified baseUri. In such cases there are
                    // not reference Uri to validate.
                    return;
                }

                string baseUriString = UriUtils.UriToString(baseUri);
                if (!uri.AbsoluteUri.StartsWith(baseUriString, StringComparison.Ordinal))
                {
                    // Skip validation if uri doesn't start with the baseUri.
                    return;
                }

                relativePath = uri.AbsoluteUri.Substring(baseUriString.Length);
            }
            else
            {
                relativePath = UriUtils.UriToString(uri);
            }

            // Trim the starting forward slashes as needed.
            while (relativePath.StartsWith("/", StringComparison.Ordinal))
            {
                relativePath = relativePath.Substring(1);
            }

            if (relativePath.Length > 0 && relativePath[0] == '$')
            {
                // If the relative path starts with '$', find the request id reference optionally ended by '/'.
                int idx = relativePath.IndexOf('/', 1);

                string referenceId = idx > 0
                    ? relativePath.Substring(1, idx - 1)
                    : relativePath.Substring(1);

                // Validate that dependsOn contains the Id reference.
                // Note that the dependsOnRequestIds here is already flattened and consists of individual request
                // ids, therefore it should contain the request id referenced by the Uri.
                if (dependsOnRequestIds == null || !dependsOnRequestIds.Contains(referenceId))
                {
                    throw new ODataException(Strings.ODataBatchReader_ReferenceIdNotIncludedInDependsOn(
                                                 referenceId, UriUtils.UriToString(uri),
                                                 dependsOnRequestIds != null ? string.Join(",", dependsOnRequestIds.ToArray()) : "null"));
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Creates the URI for a batch request operation.
        /// </summary>
        /// <param name="uri">The uri to process.</param>
        /// <param name="baseUri">The base Uri to use.</param>
        /// <param name="payloadUriConverter">An optional custom URL converter to convert URLs for writing them into the payload.</param>
        /// <returns>An URI to be used in the request line of a batch request operation. It uses the <paramref name="payloadUriConverter"/>
        /// first and falls back to the default URI building schema if the no URL resolver is specified or the URL resolver
        /// returns null. In the default scheme, the method either returns the specified <paramref name="uri"/> if it was absolute,
        /// or it's combination with the <paramref name="baseUri"/> if it was relative.</returns>
        /// <remarks>
        /// This method will fail if no custom resolution is implemented and the specified <paramref name="uri"/> is
        /// relative and there's no base URI available.
        /// </remarks>
        internal static Uri CreateOperationRequestUri(Uri uri, Uri baseUri, IODataPayloadUriConverter payloadUriConverter)
        {
            Debug.Assert(uri != null, "uri != null");

            Uri resultUri;

            if (payloadUriConverter != null)
            {
                // The resolver returns 'null' if no custom resolution is desired.
                resultUri = payloadUriConverter.ConvertPayloadUri(baseUri, uri);
                if (resultUri != null)
                {
                    return(resultUri);
                }
            }

            if (uri.IsAbsoluteUri)
            {
                resultUri = uri;
            }
            else
            {
                if (baseUri == null)
                {
                    string errorMessage = UriUtils.UriToString(uri).StartsWith("$", StringComparison.Ordinal)
                        ? Strings.ODataBatchUtils_RelativeUriStartingWithDollarUsedWithoutBaseUriSpecified(UriUtils.UriToString(uri))
                        : Strings.ODataBatchUtils_RelativeUriUsedWithoutBaseUriSpecified(UriUtils.UriToString(uri));
                    throw new ODataException(errorMessage);
                }

                resultUri = UriUtils.UriToAbsoluteUri(baseUri, uri);
            }

            return(resultUri);
        }
コード例 #5
0
        /// <summary>
        /// Sets the metadata builder for this operation.
        /// </summary>
        /// <param name="builder">The metadata builder used to compute values from model annotations.</param>
        /// <param name="metadataDocumentUri">The metadata document Uri.</param>
        internal void SetMetadataBuilder(ODataResourceMetadataBuilder builder, Uri metadataDocumentUri)
        {
            Debug.Assert(metadataDocumentUri != null, "metadataDocumentUri != null");
            Debug.Assert(metadataDocumentUri.IsAbsoluteUri, "metadataDocumentUri.IsAbsoluteUri");

            ODataJsonLightValidationUtils.ValidateOperation(metadataDocumentUri, this);
            this.metadataBuilder   = builder;
            this.operationFullName = ODataJsonLightUtils.GetFullyQualifiedOperationName(metadataDocumentUri, UriUtils.UriToString(this.Metadata), out this.parameterNames);
            this.computedTitle     = null;
            this.computedTarget    = null;
        }