Ejemplo n.º 1
0
        /// <summary>
        /// Checks whether a payload kind is supported in a request or a response.
        /// </summary>
        /// <param name="payloadKind">The <see cref="ODataPayloadKind"/> to check.</param>
        /// <param name="inRequest">true if the check is for a request; false for a response.</param>
        /// <returns>true if the <paramref name="payloadKind"/> is valid in a request or response respectively based on <paramref name="inRequest"/>.</returns>
        internal static bool IsPayloadKindSupported(ODataPayloadKind payloadKind, bool inRequest)
        {
            switch (payloadKind)
            {
            // These payload kinds are valid in requests and responses
            case ODataPayloadKind.Value:
            case ODataPayloadKind.BinaryValue:
            case ODataPayloadKind.Batch:
            case ODataPayloadKind.Resource:
            case ODataPayloadKind.Property:
            case ODataPayloadKind.EntityReferenceLink:
                return(true);

            // These payload kinds are only valid in responses
            case ODataPayloadKind.ResourceSet:
            case ODataPayloadKind.EntityReferenceLinks:
            case ODataPayloadKind.Collection:
            case ODataPayloadKind.ServiceDocument:
            case ODataPayloadKind.MetadataDocument:
            case ODataPayloadKind.Error:
            case ODataPayloadKind.IndividualProperty:
            case ODataPayloadKind.Delta:
            case ODataPayloadKind.Asynchronous:
                return(!inRequest);

            // These payload kinds are only valid in requests
            case ODataPayloadKind.Parameter:
                return(inRequest);

            // Anything else should never show up
            default:
                Debug.Assert(false, "Unsupported payload kind found: " + payloadKind.ToString());
                throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataUtilsInternal_IsPayloadKindSupported_UnreachableCodePath));
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Creates an exception which reports that the specified payload kind if not support by this format.
 /// </summary>
 /// <param name="payloadKind">The payload kind which is not supported.</param>
 /// <returns>An exception to throw.</returns>
 private ODataException CreatePayloadKindNotSupportedException(ODataPayloadKind payloadKind)
 {
     return(new ODataException(Strings.ODataInputContext_UnsupportedPayloadKindForFormat(this.format.ToString(), payloadKind.ToString())));
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Create context URL from ODataPayloadKind and ODataContextUrlInfo.
        /// should make the context uri correct for null primitive / null enum value / normal enum value
        /// ODataEnumValue is allowed to have null or arbitrary TypeName, but the output ContextUri must have correct type name.
        /// </summary>
        /// <param name="payloadKind">The ODataPayloadKind for the context URI.</param>
        /// <param name="contextInfo">The ODataContextUrlInfo to be used.</param>
        /// <returns>The generated context url.</returns>
        internal Uri BuildContextUri(ODataPayloadKind payloadKind, ODataContextUrlInfo contextInfo = null)
        {
            if (this.baseContextUrl == null)
            {
                return null;
            }

            Action<ODataContextUrlInfo> verifyAction;
            if (ValidationDictionary.TryGetValue(payloadKind, out verifyAction))
            {
                if (verifyAction != null && throwIfMissingInfo)
                {
                    Debug.Assert(contextInfo != null, "contextInfo != null");
                    verifyAction(contextInfo);
                }
            }
            else
            {
                throw new ODataException(Strings.ODataContextUriBuilder_UnsupportedPayloadKind(payloadKind.ToString()));
            }

            switch (payloadKind)
            {
                case ODataPayloadKind.ServiceDocument:
                    return this.baseContextUrl;
                case ODataPayloadKind.EntityReferenceLink:
                    return new Uri(this.baseContextUrl, ODataConstants.SingleEntityReferencesContextUrlSegment);
                case ODataPayloadKind.EntityReferenceLinks:
                    return new Uri(this.baseContextUrl, ODataConstants.CollectionOfEntityReferencesContextUrlSegment);
            }

            return CreateFromContextUrlInfo(contextInfo);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Applies the model and validates the context URI against it.
        /// </summary>
        /// <param name="expectedPayloadKind">The payload kind we expect the context URI to conform to.</param>
        /// <param name="clientCustomTypeResolver">The function of client custom type resolver.</param>
        /// <param name="throwIfMetadataConflict">Whether to throw if a type specified in the ContextUri is not found in metadata.</param>
        private void ParseContextUri(ODataPayloadKind expectedPayloadKind, Func <IEdmType, string, IEdmType> clientCustomTypeResolver, bool throwIfMetadataConflict)
        {
            bool             isUndeclared;
            ODataPayloadKind detectedPayloadKind = this.ParseContextUriFragment(this.parseResult.Fragment, clientCustomTypeResolver, throwIfMetadataConflict, out isUndeclared);

            // unsupported payload kind indicates that this is during payload kind detection, so we should not fail.
            bool     detectedPayloadKindMatchesExpectation = detectedPayloadKind == expectedPayloadKind || expectedPayloadKind == ODataPayloadKind.Unsupported;
            IEdmType parseType = this.parseResult.EdmType;

            if (parseType != null && parseType.TypeKind == EdmTypeKind.Untyped)
            {
                if (string.Equals(parseType.FullTypeName(), ODataConstants.ContextUriFragmentUntyped, StringComparison.Ordinal))
                {
                    // Anything matches the built-in Edm.Untyped
                    this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection, ODataPayloadKind.Resource };
                    detectedPayloadKindMatchesExpectation = true;
                }
                else if (expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Resource)
                {
                    // If we created an untyped type because the name was not resolved it can match any single value
                    this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Property, ODataPayloadKind.Resource };
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (parseType != null && parseType.TypeKind == EdmTypeKind.Collection && ((IEdmCollectionType)parseType).ElementType.TypeKind() == EdmTypeKind.Untyped)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection };
                if (expectedPayloadKind == ODataPayloadKind.ResourceSet || expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Collection)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.ResourceSet && parseType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection };

                if (expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Collection)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource && parseType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Collection)
            {
                // If the detected payload kind is 'collection' it can always also be treated as a property.
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Collection, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Delta };
                if (expectedPayloadKind == ODataPayloadKind.Delta)
                {
                    this.parseResult.DeltaKind            = ODataDeltaKind.Resource;
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Property && isUndeclared &&
                     (expectedPayloadKind == ODataPayloadKind.Resource || expectedPayloadKind == ODataPayloadKind.ResourceSet))
            {
                // for undeclared, we don't know whether it is a resource/resource set or not.
                this.parseResult.DetectedPayloadKinds = new[] { expectedPayloadKind, ODataPayloadKind.Property };
                detectedPayloadKindMatchesExpectation = true;
            }
            else
            {
                this.parseResult.DetectedPayloadKinds = new[] { detectedPayloadKind };
            }

            // If the expected and detected payload kinds don't match and we are not running payload kind detection
            // right now (payloadKind == ODataPayloadKind.Unsupported) and we did not detect a collection kind for
            // an expected property kind (which is allowed), fail.
            if (!detectedPayloadKindMatchesExpectation)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind(UriUtils.UriToString(this.parseResult.ContextUri), expectedPayloadKind.ToString()));
            }

            // NOTE: we interpret an empty select query option to mean that nothing should be projected
            //       (whereas a missing select query option means everything should be projected).
            string selectQueryOption = this.parseResult.SelectQueryOption;

            if (selectQueryOption != null)
            {
                if (detectedPayloadKind != ODataPayloadKind.ResourceSet && detectedPayloadKind != ODataPayloadKind.Resource && detectedPayloadKind != ODataPayloadKind.Delta)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidPayloadKindWithSelectQueryOption(expectedPayloadKind.ToString()));
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Create context URL from ODataPayloadKind and ODataContextUrlInfo.
        /// BUG 1659341: should make the context uri correct for null primitive / null enum value / normal enum value
        /// ODataEnumValue is allowed to have null or arbitrary TypeName, but the output ContextUri must have correct type name.
        /// </summary>
        /// <param name="payloadKind">The ODataPayloadKind for the context URI.</param>
        /// <param name="contextInfo">The ODataContextUrlInfo to be used.</param>
        /// <returns>The generated context url.</returns>
        internal Uri BuildContextUri(ODataPayloadKind payloadKind, ODataContextUrlInfo contextInfo = null)
        {
            if (this.baseContextUrl == null)
            {
                return(null);
            }

            Action <ODataContextUrlInfo> verifyAction;

            if (ValidationDictionary.TryGetValue(payloadKind, out verifyAction))
            {
                if (verifyAction != null && throwIfMissingInfo)
                {
                    Debug.Assert(contextInfo != null, "contextInfo != null");
                    verifyAction(contextInfo);
                }
            }
            else
            {
                throw new ODataException(Strings.ODataContextUriBuilder_UnsupportedPayloadKind(payloadKind.ToString()));
            }

            switch (payloadKind)
            {
            case ODataPayloadKind.ServiceDocument:
                return(this.baseContextUrl);

            case ODataPayloadKind.EntityReferenceLink:
                return(new Uri(this.baseContextUrl, ODataConstants.SingleEntityReferencesContextUrlSegment));

            case ODataPayloadKind.EntityReferenceLinks:
                return(new Uri(this.baseContextUrl, ODataConstants.CollectionOfEntityReferencesContextUrlSegment));
            }

            return(CreateFromContextUrlInfo(contextInfo));
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Creates an exception which reports that the specified payload kind if not support by this format.
 /// </summary>
 /// <param name="payloadKind">The payload kind which is not supported.</param>
 /// <returns>An exception to throw.</returns>
 private ODataException CreatePayloadKindNotSupportedException(ODataPayloadKind payloadKind)
 {
     return new ODataException(Strings.ODataOutputContext_UnsupportedPayloadKindForFormat(this.format.ToString(), payloadKind.ToString()));
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Applies the model and validates the context URI against it.
        /// </summary>
        /// <param name="expectedPayloadKind">The payload kind we expect the context URI to conform to.</param>
        /// <param name="readerBehavior">Reader behavior if the caller is a reader, null if no reader behavior is available.</param>
        private void ParseContextUri(ODataPayloadKind expectedPayloadKind, ODataReaderBehavior readerBehavior)
        {
            ODataPayloadKind detectedPayloadKind = this.ParseContextUriFragment(this.parseResult.Fragment, readerBehavior);

            // unsupported payload kind indicates that this is during payload kind detection, so we should not fail.
            bool detectedPayloadKindMatchesExpectation = detectedPayloadKind == expectedPayloadKind || expectedPayloadKind == ODataPayloadKind.Unsupported;

            if (detectedPayloadKind == ODataPayloadKind.Collection)
            {
                // If the detected payload kind is 'collection' it can always also be treated as a property.
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Collection, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Entry)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Entry, ODataPayloadKind.Delta };
                if (expectedPayloadKind == ODataPayloadKind.Delta)
                {
                    this.parseResult.DeltaKind            = ODataDeltaKind.Entry;
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else
            {
                this.parseResult.DetectedPayloadKinds = new[] { detectedPayloadKind };
            }

            // If the expected and detected payload kinds don't match and we are not running payload kind detection
            // right now (payloadKind == ODataPayloadKind.Unsupported) and we did not detect a collection kind for
            // an expected property kind (which is allowed), fail.
            if (!detectedPayloadKindMatchesExpectation)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind(UriUtils.UriToString(this.parseResult.ContextUri), expectedPayloadKind.ToString()));
            }

            // NOTE: we interpret an empty select query option to mean that nothing should be projected
            //       (whereas a missing select query option means everything should be projected).
            string selectQueryOption = this.parseResult.SelectQueryOption;

            if (selectQueryOption != null)
            {
                if (detectedPayloadKind != ODataPayloadKind.Feed && detectedPayloadKind != ODataPayloadKind.Entry && detectedPayloadKind != ODataPayloadKind.Delta)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidPayloadKindWithSelectQueryOption(expectedPayloadKind.ToString()));
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Checks whether a payload kind is supported in a request or a response.
        /// </summary>
        /// <param name="payloadKind">The <see cref="ODataPayloadKind"/> to check.</param>
        /// <param name="inRequest">true if the check is for a request; false for a response.</param>
        /// <returns>true if the <paramref name="payloadKind"/> is valid in a request or response respectively based on <paramref name="inRequest"/>.</returns>
        internal static bool IsPayloadKindSupported(ODataPayloadKind payloadKind, bool inRequest)
        {
            DebugUtils.CheckNoExternalCallers();

            switch (payloadKind)
            {
                // These payload kinds are valid in requests and responses
                case ODataPayloadKind.Value:
                case ODataPayloadKind.BinaryValue:
                case ODataPayloadKind.Batch:
                case ODataPayloadKind.Entry:
                case ODataPayloadKind.Property:
                case ODataPayloadKind.EntityReferenceLink:
                    return true;

                // These payload kinds are only valid in responses
                case ODataPayloadKind.Feed:
                case ODataPayloadKind.EntityReferenceLinks:
                case ODataPayloadKind.Collection:
                case ODataPayloadKind.ServiceDocument:
                case ODataPayloadKind.MetadataDocument:
                case ODataPayloadKind.Error:
                    return !inRequest;

                // These payload kidns are only valid in requests
                case ODataPayloadKind.Parameter:
                    return inRequest;

                // Anything else should never show up
                default:
                    Debug.Assert(false, "Unsupported payload kind found: " + payloadKind.ToString());
                    throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataUtilsInternal_IsPayloadKindSupported_UnreachableCodePath));
            }
        }
        /// <summary>
        /// Applies the model and validates the context URI against it.
        /// </summary>
        /// <param name="expectedPayloadKind">The payload kind we expect the context URI to conform to.</param>
        /// <param name="readerBehavior">Reader behavior if the caller is a reader, null if no reader behavior is available.</param>
        private void ParseContextUri(ODataPayloadKind expectedPayloadKind, ODataReaderBehavior readerBehavior)
        {
            ODataPayloadKind detectedPayloadKind = this.ParseContextUriFragment(this.parseResult.Fragment, readerBehavior);

            // unsupported payload kind indicates that this is during payload kind detection, so we should not fail.
            bool detectedPayloadKindMatchesExpectation = detectedPayloadKind == expectedPayloadKind || expectedPayloadKind == ODataPayloadKind.Unsupported;
            if (detectedPayloadKind == ODataPayloadKind.Collection)
            {
                // If the detected payload kind is 'collection' it can always also be treated as a property.
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Collection, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Entry)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Entry, ODataPayloadKind.Delta };
                if (expectedPayloadKind == ODataPayloadKind.Delta)
                {
                    this.parseResult.DeltaKind = ODataDeltaKind.Entry;
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else
            {
                this.parseResult.DetectedPayloadKinds = new[] { detectedPayloadKind };
            }

            // If the expected and detected payload kinds don't match and we are not running payload kind detection
            // right now (payloadKind == ODataPayloadKind.Unsupported) and we did not detect a collection kind for
            // an expected property kind (which is allowed), fail.
            if (!detectedPayloadKindMatchesExpectation)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind(UriUtils.UriToString(this.parseResult.ContextUri), expectedPayloadKind.ToString()));
            }

            // NOTE: we interpret an empty select query option to mean that nothing should be projected
            //       (whereas a missing select query option means everything should be projected).
            string selectQueryOption = this.parseResult.SelectQueryOption;
            if (selectQueryOption != null)
            {
                if (detectedPayloadKind != ODataPayloadKind.Feed && detectedPayloadKind != ODataPayloadKind.Entry && detectedPayloadKind != ODataPayloadKind.Delta)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidPayloadKindWithSelectQueryOption(expectedPayloadKind.ToString()));
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Get the supported media types for a payload kind.
        /// </summary>
        /// <param name="kind">The <see cref="ODataPayloadKind"/> to get the supported media types for.</param>
        /// <param name="includeApplicationJson">true if application/json should be included as supported media type (for reading versions &lt; V3).</param>
        /// <param name="includeApplicationJsonLight">true if JsonLight media types should be included.</param>
        /// <returns>The string concatenating all supported media types for <paramref name="kind"/>.</returns>
        public static string GetSupportedMediaTypes(ODataPayloadKind kind, bool includeApplicationJson = true, bool includeApplicationJsonLight = true)
        {
            StringBuilder builder         = new StringBuilder();
            bool          hasTailingComma = false;

            // Add the JSON media types to the supported payload kinds
            switch (kind)
            {
            case ODataPayloadKind.ResourceSet:
            case ODataPayloadKind.Resource:
            case ODataPayloadKind.Property:
            case ODataPayloadKind.Collection:
            case ODataPayloadKind.EntityReferenceLink:
            case ODataPayloadKind.EntityReferenceLinks:
            case ODataPayloadKind.Error:
            case ODataPayloadKind.ServiceDocument:
            case ODataPayloadKind.Parameter:
                AddJsonMediaTypes(includeApplicationJson, includeApplicationJsonLight, builder);
                break;

            default:
                break;
            }

            switch (kind)
            {
            case ODataPayloadKind.ResourceSet:
            case ODataPayloadKind.EntityReferenceLinks:
                break;

            case ODataPayloadKind.Resource:
                break;

            case ODataPayloadKind.Property:
                break;

            case ODataPayloadKind.Collection:
                break;

            case ODataPayloadKind.Value:
                builder.Append("text/plain");
                break;

            case ODataPayloadKind.BinaryValue:
                builder.Append("application/octet-stream");
                break;

            case ODataPayloadKind.EntityReferenceLink:
                break;

            case ODataPayloadKind.Error:
                break;

            case ODataPayloadKind.ServiceDocument:
                break;

            case ODataPayloadKind.Batch:
                builder.Append("multipart/mixed, ");
                AddJsonMediaTypes(includeApplicationJson, includeApplicationJsonLight, builder);
                hasTailingComma = true;
                break;

            case ODataPayloadKind.MetadataDocument:
                break;

            case ODataPayloadKind.Parameter:
                builder.Append(string.Empty);
                break;

            case ODataPayloadKind.Unsupported:
            default:
                throw new NotSupportedException("Unsupported payload kind found: " + kind.ToString());
            }

            return(hasTailingComma
                    ? builder.ToString(0, builder.Length - 1)
                    : builder.ToString());
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Gets the default content type for a given payload kind and format.
        /// </summary>
        /// <param name="kind">The payload kind to get the default format for.</param>
        /// <param name="format">The format from the test configuration.</param>
        /// <returns>The default content type used by the message writer.</returns>
        public static string GetDefaultContentType(ODataPayloadKind kind, ODataFormat format)
        {
            switch (kind)
            {
            case ODataPayloadKind.ResourceSet:
            case ODataPayloadKind.EntityReferenceLinks:
                if (format == ODataFormat.Json)
                {
                    return("application/json;odata.metadata=minimal;odata.streaming=true;charset=utf-8");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Resource:
                if (format == ODataFormat.Json)
                {
                    return("application/json;odata.metadata=minimal;odata.streaming=true;charset=utf-8");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Value:
                if (format == ODataFormat.RawValue || format == null)
                {
                    return("text/plain;charset=iso-8859-1");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.BinaryValue:
                if (format == ODataFormat.RawValue || format == null)
                {
                    return("application/octet-stream");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Property:                 // fall through
            case ODataPayloadKind.Collection:               // fall through
            case ODataPayloadKind.EntityReferenceLink:      // fall through
            case ODataPayloadKind.Error:                    // fall through
            case ODataPayloadKind.ServiceDocument:
                if (format == ODataFormat.Json)
                {
                    return("application/json;odata.metadata=minimal;odata.streaming=true;charset=utf-8");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Batch:
                if (format == ODataFormat.Batch || format == null)
                {
                    return("multipart/mixed");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.MetadataDocument:
                if (format == ODataFormat.Metadata || format == null)
                {
                    return("application/xml");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Parameter:
                if (format == ODataFormat.Json)
                {
                    return("application/json;odata.metadata=minimal;odata.streaming=true;charset=utf-8");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Unsupported:
            default:
                throw new NotSupportedException("Unsupported payload kind found: " + kind.ToString());
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Applies the model and validates the context URI against it.
        /// </summary>
        /// <param name="expectedPayloadKind">The payload kind we expect the context URI to conform to.</param>
        /// <param name="clientCustomTypeResolver">The function of client cuetom type resolver.</param>
        private void ParseContextUri(ODataPayloadKind expectedPayloadKind, Func <IEdmType, string, IEdmType> clientCustomTypeResolver)
        {
            bool             isUndeclared        = false;
            ODataPayloadKind detectedPayloadKind = this.ParseContextUriFragment(this.parseResult.Fragment, clientCustomTypeResolver, out isUndeclared);

            // unsupported payload kind indicates that this is during payload kind detection, so we should not fail.
            bool detectedPayloadKindMatchesExpectation = detectedPayloadKind == expectedPayloadKind || expectedPayloadKind == ODataPayloadKind.Unsupported;

            if (detectedPayloadKind == ODataPayloadKind.ResourceSet && this.parseResult.EdmType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection };

                if (expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Collection)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource && this.parseResult.EdmType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Collection)
            {
                // If the detected payload kind is 'collection' it can always also be treated as a property.
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Collection, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Delta };
                if (expectedPayloadKind == ODataPayloadKind.Delta)
                {
                    this.parseResult.DeltaKind            = ODataDeltaKind.Resource;
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Property && isUndeclared &&
                     (expectedPayloadKind == ODataPayloadKind.Resource || expectedPayloadKind == ODataPayloadKind.ResourceSet))
            {
                // for undeclared, we don't know whether it is a resource/resource set or not.
                this.parseResult.DetectedPayloadKinds = new[] { expectedPayloadKind, ODataPayloadKind.Property };
                detectedPayloadKindMatchesExpectation = true;
            }
            else
            {
                this.parseResult.DetectedPayloadKinds = new[] { detectedPayloadKind };
            }

            // If the expected and detected payload kinds don't match and we are not running payload kind detection
            // right now (payloadKind == ODataPayloadKind.Unsupported) and we did not detect a collection kind for
            // an expected property kind (which is allowed), fail.
            if (!detectedPayloadKindMatchesExpectation)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind(UriUtils.UriToString(this.parseResult.ContextUri), expectedPayloadKind.ToString()));
            }

            // NOTE: we interpret an empty select query option to mean that nothing should be projected
            //       (whereas a missing select query option means everything should be projected).
            string selectQueryOption = this.parseResult.SelectQueryOption;

            if (selectQueryOption != null)
            {
                if (detectedPayloadKind != ODataPayloadKind.ResourceSet && detectedPayloadKind != ODataPayloadKind.Resource && detectedPayloadKind != ODataPayloadKind.Delta)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidPayloadKindWithSelectQueryOption(expectedPayloadKind.ToString()));
                }
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Get the supported media types for a payload kind.
        /// </summary>
        /// <param name="kind">The <see cref="ODataPayloadKind"/> to get the supported media types for.</param>
        /// <param name="includeApplicationJson">true if application/json should be included as supported media type (for reading versions &lt; V3).</param>
        /// <returns>The string concatenating all supported media types for <paramref name="kind"/>.</returns>
        public static string GetSupportedMediaTypes(ODataPayloadKind kind, bool includeApplicationJson = true, bool includeApplicationJsonLight = true)
        {
            StringBuilder builder = new StringBuilder();

            // Add the JSON media types to the supported payload kinds
            switch (kind)
            {
            case ODataPayloadKind.Feed:
            case ODataPayloadKind.Entry:
            case ODataPayloadKind.Property:
            case ODataPayloadKind.Collection:
            case ODataPayloadKind.EntityReferenceLink:
            case ODataPayloadKind.EntityReferenceLinks:
            case ODataPayloadKind.Error:
            case ODataPayloadKind.ServiceDocument:
            case ODataPayloadKind.Parameter:
                if (includeApplicationJsonLight)
                {
                    builder.Append("application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.metadata=minimal;odata.streaming=true");
                    builder.Append(", application/json;odata.metadata=minimal;odata.streaming=false;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.metadata=minimal;odata.streaming=false;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.metadata=minimal;odata.streaming=false");
                    builder.Append(", application/json;odata.metadata=minimal;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.metadata=minimal;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.metadata=minimal");
                    builder.Append(", application/json;odata.metadata=full;odata.streaming=true;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.metadata=full;odata.streaming=true;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.metadata=full;odata.streaming=true");
                    builder.Append(", application/json;odata.metadata=full;odata.streaming=false;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.metadata=full;odata.streaming=false;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.metadata=full;odata.streaming=false");
                    builder.Append(", application/json;odata.metadata=full;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.metadata=full;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.metadata=full");
                    builder.Append(", application/json;odata.metadata=none;odata.streaming=true;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.metadata=none;odata.streaming=true;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.metadata=none;odata.streaming=true");
                    builder.Append(", application/json;odata.metadata=none;odata.streaming=false;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.metadata=none;odata.streaming=false;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.metadata=none;odata.streaming=false");
                    builder.Append(", application/json;odata.metadata=none;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.metadata=none;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.metadata=none");
                    builder.Append(", application/json;odata.streaming=true;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.streaming=true;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.streaming=true");
                    builder.Append(", application/json;odata.streaming=false;IEEE754Compatible=false");
                    builder.Append(", application/json;odata.streaming=false;IEEE754Compatible=true");
                    builder.Append(", application/json;odata.streaming=false");
                    builder.Append(", application/json;IEEE754Compatible=false");
                    builder.Append(", application/json;IEEE754Compatible=true");
                    builder.Append(", ");
                }

                if (includeApplicationJson)
                {
                    builder.Append("application/json");
                    builder.Append(", ");
                }
                break;

            default:
                break;
            }

            switch (kind)
            {
            case ODataPayloadKind.Feed:
            case ODataPayloadKind.EntityReferenceLinks:
                break;

            case ODataPayloadKind.Entry:
                break;

            case ODataPayloadKind.Property:
                break;

            case ODataPayloadKind.Collection:
                break;

            case ODataPayloadKind.Value:
                builder.Append("text/plain");
                break;

            case ODataPayloadKind.BinaryValue:
                builder.Append("application/octet-stream");
                break;

            case ODataPayloadKind.EntityReferenceLink:
                break;

            case ODataPayloadKind.Error:
                break;

            case ODataPayloadKind.ServiceDocument:
                break;

            case ODataPayloadKind.Batch:
                builder.Append("multipart/mixed");
                break;

            case ODataPayloadKind.MetadataDocument:
                break;

            case ODataPayloadKind.Parameter:
                builder.Append(string.Empty);
                break;

            case ODataPayloadKind.Unsupported:
            default:
                throw new NotSupportedException("Unsupported payload kind found: " + kind.ToString());
            }

            return(builder.ToString());
        }