Beispiel #1
0
 private static ODataPayloadElementCollection CreateCollectionForElementType(ODataPayloadElementType elementType)
 {
     if (elementType == ODataPayloadElementType.PrimitiveValue)
     {
         return(new PrimitiveCollection());
     }
     else if (elementType == ODataPayloadElementType.DeferredLink)
     {
         return(new LinkCollection());
     }
     else if (elementType == ODataPayloadElementType.ComplexInstance)
     {
         return(new ComplexInstanceCollection());
     }
     else
     {
         ExceptionUtilities.Assert(elementType == ODataPayloadElementType.EntityInstance, "Element type was unexpected type '{0}'", elementType);
         return(new EntitySetInstance());
     }
 }
Beispiel #2
0
 private static ODataPayloadElement CreateNullElement(ODataPayloadElementType elementType)
 {
     if (elementType == ODataPayloadElementType.PrimitiveValue)
     {
         return(new PrimitiveValue(null, null));
     }
     else if (elementType == ODataPayloadElementType.DeferredLink)
     {
         return(new DeferredLink());
     }
     else if (elementType == ODataPayloadElementType.ComplexInstance)
     {
         return(new ComplexInstance(null, true));
     }
     else
     {
         ExceptionUtilities.Assert(elementType == ODataPayloadElementType.EntityInstance, "Element type was unexpected type '{0}'", elementType);
         return(new EntityInstance(null, true));
     }
 }
 private static void AssertIsSupportedElementType(ODataPayloadElementType elementType)
 {
     ExceptionUtilities.Assert(supportedElementTypes.Contains(elementType), "Unsupported element type: '{0}'", elementType);
 }
Beispiel #4
0
        /// <summary>
        /// Determines whether the request manager should try to resolve the payload's metadata
        /// </summary>
        /// <param name="requestUri">The request uri</param>
        /// <param name="responseStatusCode">The response status code</param>
        /// <param name="responsePayloadType">The response payload type</param>
        /// <returns>True if it should resolve the metadata, false otherwise</returns>
        internal static bool ShouldResolveMetadata(ODataUri requestUri, HttpStatusCode responseStatusCode, ODataPayloadElementType responsePayloadType)
        {
            ExceptionUtilities.CheckArgumentNotNull(requestUri, "requestUri");

            if (responseStatusCode.IsError())
            {
                return(false);
            }

            if (requestUri.IsNamedStream() || requestUri.IsMediaResource())
            {
                return(false);
            }

            if (responsePayloadType == ODataPayloadElementType.MetadataPayloadElement ||
                responsePayloadType == ODataPayloadElementType.HtmlErrorPayload ||
                responsePayloadType == ODataPayloadElementType.ODataErrorPayload)
            {
                return(false);
            }

            return(true);
        }
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="model">The model used to resolve the metadata.</param>
            /// <param name="payloadElement">The payload element to get the reader metadata for.</param>
            public ReaderMetadata(IEdmModel model, ODataPayloadElement payloadElement)
            {
                var expectedTypeAnnotation = payloadElement.GetAnnotation <ExpectedTypeODataPayloadElementAnnotation>();

                // NOTE: we don't require a model for the computation of the expected type (since the expected one might be a primitive type).
                this.expectedType = GetExpectedType(expectedTypeAnnotation, model);

                // We need a model for all the other expected reader metadata
                if (model == null)
                {
                    // If the annotation specified some model dependent data (basically anything but primitive expected type)
                    // and we don't have a model, we wouldn't be able to correctly represent it here (since we need the model to resolve these)
                    // and thus we should not pass in the expected type alone, as that would be changing the intent of the annotation.
                    if (expectedTypeAnnotation != null &&
                        (expectedTypeAnnotation.EntitySet != null ||
                         expectedTypeAnnotation.EdmEntitySet != null ||
                         expectedTypeAnnotation.FunctionImport != null ||
                         expectedTypeAnnotation.ProductFunctionImport != null ||
                         expectedTypeAnnotation.MemberProperty != null ||
                         expectedTypeAnnotation.EdmProperty != null ||
                         expectedTypeAnnotation.NavigationProperty != null ||
                         expectedTypeAnnotation.EdmNavigationProperty != null ||
                         expectedTypeAnnotation.OpenMemberPropertyName != null ||
                         expectedTypeAnnotation.OwningType != null ||
                         expectedTypeAnnotation.EdmOwningType != null))
                    {
                        this.expectedType = null;
                    }

                    return;
                }

                ODataPayloadElementType elementType = payloadElement.ElementType;

                switch (elementType)
                {
                case ODataPayloadElementType.EntityInstance:        // fall through
                case ODataPayloadElementType.EntitySetInstance:
                    this.entitySet = GetExpectedEntitySet(expectedTypeAnnotation, model, payloadElement);
                    break;

                case ODataPayloadElementType.DeferredLink:          // fall through
                case ODataPayloadElementType.LinkCollection:
                    this.navigationProperty = GetExpectedNavigationProperty(expectedTypeAnnotation, model);
                    break;

                case ODataPayloadElementType.PrimitiveMultiValueProperty:       // fall through
                case ODataPayloadElementType.PrimitiveProperty:                 // fall through
                case ODataPayloadElementType.ComplexProperty:                   // fall through
                case ODataPayloadElementType.ComplexMultiValueProperty:         // fall through
                case ODataPayloadElementType.EmptyCollectionProperty:
                    this.structuralProperty = GetExpectedStructuralProperty(expectedTypeAnnotation, model);
                    this.functionImport     = GetExpectedFunctionImport(expectedTypeAnnotation, model);
                    break;

                case ODataPayloadElementType.ComplexInstanceCollection:         // fall through
                case ODataPayloadElementType.PrimitiveCollection:               // fall through
                case ODataPayloadElementType.EmptyUntypedCollection:
                    this.functionImport = GetExpectedFunctionImport(expectedTypeAnnotation, model);
                    break;

                case ODataPayloadElementType.ComplexInstance:
                    // NOTE: this is how we model parameter payloads
                    this.functionImport = GetExpectedFunctionImport(expectedTypeAnnotation, model);
                    break;
                }
            }
        /// <summary>
        /// Builds a context URI from the expected type annotation.
        /// </summary>
        /// <param name="payloadElementKind">The payload element kind to build the context URI for.</param>
        /// <param name="metadataDocumentUri">The metadata document URI.</param>
        /// <param name="expectedTypeAnnotation">The expected type annotation.</param>
        /// <returns>The constructed context URI.</returns>
        public static string BuildContextUri(ODataPayloadElementType payloadElementKind, string metadataDocumentUri, ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, string projectionString = null)
        {
            ExceptionUtilities.CheckArgumentNotNull(metadataDocumentUri, "metadataDocumentUri");
            ExceptionUtilities.CheckArgumentNotNull(expectedTypeAnnotation, "expectedTypeAnnotation");

            StringBuilder builder = new StringBuilder(metadataDocumentUri);

            switch (payloadElementKind)
            {
            // Entry payload
            case ODataPayloadElementType.EntityInstance:
            {
                EdmEntitySet entitySet = (EdmEntitySet)expectedTypeAnnotation.EdmEntitySet;
                ExceptionUtilities.Assert(entitySet != null, "Entity set is required for entry payloads.");

                builder.Append('#');
                AppendEntityContainerElement(builder, entitySet.Container, entitySet.Name);
                AppendTypeCastIfNeeded(builder, entitySet, expectedTypeAnnotation.EdmExpectedType.Definition);
                builder.Append(projectionString);
                builder.Append("/$entity");

                break;
            }

            // Feed payload
            case ODataPayloadElementType.EntitySetInstance:
            {
                EdmEntitySet entitySet = (EdmEntitySet)expectedTypeAnnotation.EdmEntitySet;
                ExceptionUtilities.Assert(entitySet != null, "Entity set is required for feed payloads.");
                builder.Append('#');
                AppendEntityContainerElement(builder, entitySet.Container, entitySet.Name);
                AppendTypeCastIfNeeded(builder, entitySet, expectedTypeAnnotation.EdmExpectedType.Definition);
                builder.Append(projectionString);

                break;
            }

            // Property payload
            case ODataPayloadElementType.PrimitiveProperty:                 // fall through
            case ODataPayloadElementType.PrimitiveMultiValueProperty:       // fall through
            case ODataPayloadElementType.ComplexMultiValueProperty:         // fall through
            case ODataPayloadElementType.ComplexProperty:                   // fall through
            case ODataPayloadElementType.NullPropertyInstance:
            // Collection payload
            case ODataPayloadElementType.EmptyCollectionProperty:       // fall through
            case ODataPayloadElementType.ComplexInstanceCollection:     // fall through
            case ODataPayloadElementType.PrimitiveCollection:
                builder.Append('#');

                // NOTE: property payloads can be produced by regular properties as well as function imports
                IEdmTypeReference edmExpectedType = null;
                if (expectedTypeAnnotation.EdmProperty != null)
                {
                    edmExpectedType = expectedTypeAnnotation.EdmProperty.Type;
                }
                else if (expectedTypeAnnotation.ProductFunctionImport != null)
                {
                    edmExpectedType = expectedTypeAnnotation.ProductFunctionImport.Operation.ReturnType;
                }
                else if (expectedTypeAnnotation.EdmExpectedType != null)
                {
                    edmExpectedType = expectedTypeAnnotation.EdmExpectedType;
                }

                if (edmExpectedType == null)
                {
                    if (expectedTypeAnnotation.EdmExpectedType != null)
                    {
                        AppendTypeName(builder, expectedTypeAnnotation.EdmExpectedType.Definition);
                    }
                    else if (expectedTypeAnnotation.ProductFunctionImport != null)
                    {
                        AppendTypeName(builder, expectedTypeAnnotation.ProductFunctionImport.Operation.ReturnType.Definition);
                    }
                }
                else
                {
                    AppendTypeName(builder, edmExpectedType.Definition);
                }

                break;

            // Entity reference link payload
            case ODataPayloadElementType.DeferredLink:
            case ODataPayloadElementType.LinkCollection:
            {
                IEdmEntitySet         entitySet          = expectedTypeAnnotation.EdmEntitySet;
                EdmNavigationProperty navigationProperty = expectedTypeAnnotation.EdmNavigationProperty as EdmNavigationProperty;
                IEdmEntityType        entityType         = navigationProperty.DeclaringEntityType;

                ExceptionUtilities.Assert(entitySet != null, "entitySet is required for entity reference link payloads.");
                ExceptionUtilities.Assert(navigationProperty != null, "Navigation property is required for entity reference link payloads.");

                builder.Append('#');

                if (payloadElementKind == ODataPayloadElementType.DeferredLink)
                {
                    builder.Append("$ref");
                }
                else if (payloadElementKind == ODataPayloadElementType.LinkCollection)
                {
                    builder.Append("Collection($ref)");
                }

                break;
            }

            // Service document payload
            case ODataPayloadElementType.ServiceDocumentInstance:       // fall through
            case ODataPayloadElementType.WorkspaceInstance:
                // NOTE: the builder already contains the metadata document URI.
                break;

            default:
                return(null);
            }

            return(builder.ToString());
        }
        /// <summary>
        /// Determines whether the request manager should try to resolve the payload's metadata
        /// </summary>
        /// <param name="requestUri">The request uri</param>
        /// <param name="responseStatusCode">The response status code</param>
        /// <param name="responsePayloadType">The response payload type</param>
        /// <returns>True if it should resolve the metadata, false otherwise</returns>
        internal static bool ShouldResolveMetadata(ODataUri requestUri, HttpStatusCode responseStatusCode, ODataPayloadElementType responsePayloadType)
        {
            ExceptionUtilities.CheckArgumentNotNull(requestUri, "requestUri");

            if (responseStatusCode.IsError())
            {
                return false;
            }

            if (requestUri.IsNamedStream() || requestUri.IsMediaResource())
            {
                return false;
            }

            if (responsePayloadType == ODataPayloadElementType.MetadataPayloadElement 
                || responsePayloadType == ODataPayloadElementType.HtmlErrorPayload 
                || responsePayloadType == ODataPayloadElementType.ODataErrorPayload)
            {
                return false;
            }

            return true;
        }