Esempio n. 1
0
        private void WriteEntryContent(ODataEntry entry, IEdmEntityType entryType, EntryPropertiesValueCache propertiesValueCache, EpmSourcePathSegment rootSourcePathSegment, ProjectedPropertiesAnnotation projectedProperties)
        {
            ODataStreamReferenceValue mediaResource = entry.MediaResource;

            if (mediaResource == null)
            {
                this.atomOutputContext.XmlWriter.WriteStartElement("", "content", "http://www.w3.org/2005/Atom");
                this.atomOutputContext.XmlWriter.WriteAttributeString("type", "application/xml");
                this.atomEntryAndFeedSerializer.WriteProperties(entryType, propertiesValueCache.EntryProperties, false, new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart), new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd), base.DuplicatePropertyNamesChecker, propertiesValueCache, rootSourcePathSegment, projectedProperties);
                this.atomOutputContext.XmlWriter.WriteEndElement();
            }
            else
            {
                WriterValidationUtils.ValidateStreamReferenceValue(mediaResource, true);
                this.atomEntryAndFeedSerializer.WriteEntryMediaEditLink(mediaResource);
                if (mediaResource.ReadLink != null)
                {
                    this.atomOutputContext.XmlWriter.WriteStartElement("", "content", "http://www.w3.org/2005/Atom");
                    this.atomOutputContext.XmlWriter.WriteAttributeString("type", mediaResource.ContentType);
                    this.atomOutputContext.XmlWriter.WriteAttributeString("src", this.atomEntryAndFeedSerializer.UriToUrlAttributeValue(mediaResource.ReadLink));
                    this.atomOutputContext.XmlWriter.WriteEndElement();
                }
                this.atomEntryAndFeedSerializer.WriteProperties(entryType, propertiesValueCache.EntryProperties, false, new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart), new Action(this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd), base.DuplicatePropertyNamesChecker, propertiesValueCache, rootSourcePathSegment, projectedProperties);
            }
        }
        /// <summary>
        /// Writes a stream property to the ATOM payload
        /// </summary>
        /// <param name="streamProperty">The stream property to create the payload for.</param>
        /// <param name="owningType">The <see cref="IEdmEntityType"/> instance for which the stream property defined on.</param>
        /// <param name="duplicatePropertyNamesChecker">The checker instance for duplicate property names.</param>
        /// <param name="projectedProperties">Set of projected properties, or null if all properties should be written.</param>
        internal void WriteStreamProperty(
            ODataProperty streamProperty,
            IEdmEntityType owningType,
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker,
            ProjectedPropertiesAnnotation projectedProperties)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(streamProperty != null, "Stream property must not be null.");
            Debug.Assert(streamProperty.Value != null, "The media resource of the stream property must not be null.");

            WriterValidationUtils.ValidatePropertyNotNull(streamProperty);
            string propertyName = streamProperty.Name;

            if (projectedProperties.ShouldSkipProperty(propertyName))
            {
                return;
            }

            WriterValidationUtils.ValidatePropertyName(propertyName);
            duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(streamProperty);
            IEdmProperty edmProperty = WriterValidationUtils.ValidatePropertyDefined(streamProperty.Name, owningType, this.MessageWriterSettings.UndeclaredPropertyBehaviorKinds);

            WriterValidationUtils.ValidateStreamReferenceProperty(streamProperty, edmProperty, this.Version, this.WritingResponse);
            ODataStreamReferenceValue streamReferenceValue = (ODataStreamReferenceValue)streamProperty.Value;

            WriterValidationUtils.ValidateStreamReferenceValue(streamReferenceValue, false /*isDefaultStream*/);
            if (owningType != null && owningType.IsOpen && edmProperty == null)
            {
                ValidationUtils.ValidateOpenPropertyValue(streamProperty.Name, streamReferenceValue, this.MessageWriterSettings.UndeclaredPropertyBehaviorKinds);
            }

            AtomStreamReferenceMetadata streamReferenceMetadata = streamReferenceValue.GetAnnotation <AtomStreamReferenceMetadata>();
            string contentType = streamReferenceValue.ContentType;
            string linkTitle   = streamProperty.Name;

            Uri readLink = streamReferenceValue.ReadLink;

            if (readLink != null)
            {
                string readLinkRelation = AtomUtils.ComputeStreamPropertyRelation(streamProperty, false);

                AtomLinkMetadata readLinkMetadata = streamReferenceMetadata == null ? null : streamReferenceMetadata.SelfLink;
                AtomLinkMetadata mergedMetadata   = ODataAtomWriterMetadataUtils.MergeLinkMetadata(readLinkMetadata, readLinkRelation, readLink, linkTitle, contentType);
                this.atomEntryMetadataSerializer.WriteAtomLink(mergedMetadata, null /* etag */);
            }

            Uri editLink = streamReferenceValue.EditLink;

            if (editLink != null)
            {
                string editLinkRelation = AtomUtils.ComputeStreamPropertyRelation(streamProperty, true);

                AtomLinkMetadata editLinkMetadata = streamReferenceMetadata == null ? null : streamReferenceMetadata.EditLink;
                AtomLinkMetadata mergedMetadata   = ODataAtomWriterMetadataUtils.MergeLinkMetadata(editLinkMetadata, editLinkRelation, editLink, linkTitle, contentType);
                this.atomEntryMetadataSerializer.WriteAtomLink(mergedMetadata, streamReferenceValue.ETag);
            }
        }
        /// <summary>
        /// Writes the __metadata property and its content for an entry
        /// </summary>
        /// <param name="entry">The entry for which to write the metadata.</param>
        /// <param name="projectedProperties">Set of projected properties, or null if all properties should be written.</param>
        /// <param name="entryEntityType">The entity type of the entry to write.</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker to use.</param>
        internal void WriteEntryMetadata(
            ODataEntry entry,
            ProjectedPropertiesAnnotation projectedProperties,
            IEdmEntityType entryEntityType,
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(entry != null, "entry != null");

            // Write the "__metadata" for the entry
            this.JsonWriter.WriteName(JsonConstants.ODataMetadataName);
            this.JsonWriter.StartObjectScope();

            // Write the "id": "Entity Id"
            string id = entry.Id;

            if (id != null)
            {
                this.JsonWriter.WriteName(JsonConstants.ODataEntryIdName);
                this.JsonWriter.WriteValue(id);
            }

            // Write the "uri": "edit/read-link-uri"
            Uri uriValue = entry.EditLink ?? entry.ReadLink;

            if (uriValue != null)
            {
                this.JsonWriter.WriteName(JsonConstants.ODataMetadataUriName);
                this.JsonWriter.WriteValue(this.UriToAbsoluteUriString(uriValue));
            }

            // Write the "etag": "ETag value"
            // TODO: if this is a top-level entry also put the ETag into the headers.
            string etag = entry.ETag;

            if (etag != null)
            {
                this.WriteETag(JsonConstants.ODataMetadataETagName, etag);
            }

            // Write the "type": "typename"
            string typeName = this.VerboseJsonOutputContext.TypeNameOracle.GetEntryTypeNameForWriting(entry);

            if (typeName != null)
            {
                this.JsonWriter.WriteName(JsonConstants.ODataMetadataTypeName);
                this.JsonWriter.WriteValue(typeName);
            }

            // Write MLE metadata
            ODataStreamReferenceValue mediaResource = entry.MediaResource;

            if (mediaResource != null)
            {
                WriterValidationUtils.ValidateStreamReferenceValue(mediaResource, true);
                this.WriteStreamReferenceValueContent(mediaResource);
            }

            // write "actions" metadata
            IEnumerable <ODataAction> actions = entry.Actions;

            if (actions != null)
            {
                this.WriteOperations(actions.Cast <ODataOperation>(), JsonConstants.ODataActionsMetadataName, /*isAction*/ true, /*writingJsonLight*/ false);
            }

            // write "functions" metadata
            IEnumerable <ODataFunction> functions = entry.Functions;

            if (functions != null)
            {
                this.WriteOperations(functions.Cast <ODataOperation>(), JsonConstants.ODataFunctionsMetadataName, /*isAction*/ false, /*writingJsonLight*/ false);
            }

            // Write properties metadata
            // For now only association links are supported here
            IEnumerable <ODataAssociationLink> associationLinks = entry.AssociationLinks;

            if (associationLinks != null)
            {
                bool firstAssociationLink = true;

                foreach (ODataAssociationLink associationLink in associationLinks)
                {
                    ValidationUtils.ValidateAssociationLinkNotNull(associationLink);
                    if (projectedProperties.ShouldSkipProperty(associationLink.Name))
                    {
                        continue;
                    }

                    if (firstAssociationLink)
                    {
                        // Write the "properties": {
                        this.JsonWriter.WriteName(JsonConstants.ODataMetadataPropertiesName);
                        this.JsonWriter.StartObjectScope();

                        firstAssociationLink = false;
                    }

                    this.ValidateAssociationLink(associationLink, entryEntityType);
                    this.WriteAssociationLink(associationLink, duplicatePropertyNamesChecker);
                }

                if (!firstAssociationLink)
                {
                    // Close the "properties" object
                    this.JsonWriter.EndObjectScope();
                }
            }

            // Close the __metadata object scope
            this.JsonWriter.EndObjectScope();
        }
Esempio n. 4
0
        /// <summary>
        /// Write the content of the given entry.
        /// </summary>
        /// <param name="entry">The entry for which to write properties.</param>
        /// <param name="entryType">The <see cref="IEdmEntityType"/> of the entry (or null if not metadata is available).</param>
        /// <param name="propertiesValueCache">The cache of properties.</param>
        /// <param name="rootSourcePathSegment">The root of the EPM source tree, if there's an EPM applied.</param>
        /// <param name="projectedProperties">Set of projected properties, or null if all properties should be written.</param>
        private void WriteEntryContent(
            ODataEntry entry,
            IEdmEntityType entryType,
            EntryPropertiesValueCache propertiesValueCache,
            EpmSourcePathSegment rootSourcePathSegment,
            ProjectedPropertiesAnnotation projectedProperties)
        {
            Debug.Assert(entry != null, "entry != null");
            Debug.Assert(propertiesValueCache != null, "propertiesValueCache != null");

            ODataStreamReferenceValue mediaResource = entry.MediaResource;

            if (mediaResource == null)
            {
                // <content type="application/xml">
                this.atomOutputContext.XmlWriter.WriteStartElement(
                    AtomConstants.AtomNamespacePrefix,
                    AtomConstants.AtomContentElementName,
                    AtomConstants.AtomNamespace);

                this.atomOutputContext.XmlWriter.WriteAttributeString(
                    AtomConstants.AtomTypeAttributeName,
                    MimeConstants.MimeApplicationXml);

                this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero();
                this.atomEntryAndFeedSerializer.WriteProperties(
                    entryType,
                    propertiesValueCache.EntryProperties,
                    false /* isWritingCollection */,
                    this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart,
                    this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd,
                    this.DuplicatePropertyNamesChecker,
                    propertiesValueCache,
                    rootSourcePathSegment,
                    projectedProperties);
                this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero();

                // </content>
                this.atomOutputContext.XmlWriter.WriteEndElement();
            }
            else
            {
                WriterValidationUtils.ValidateStreamReferenceValue(mediaResource, true);

                this.atomEntryAndFeedSerializer.WriteEntryMediaEditLink(mediaResource);

                if (mediaResource.ReadLink != null)
                {
                    // <content type="type" src="src">
                    this.atomOutputContext.XmlWriter.WriteStartElement(
                        AtomConstants.AtomNamespacePrefix,
                        AtomConstants.AtomContentElementName,
                        AtomConstants.AtomNamespace);

                    Debug.Assert(!string.IsNullOrEmpty(mediaResource.ContentType), "The default stream content type should have been validated by now. If we have a read link we must have a non-empty content type as well.");
                    this.atomOutputContext.XmlWriter.WriteAttributeString(
                        AtomConstants.AtomTypeAttributeName,
                        mediaResource.ContentType);

                    this.atomOutputContext.XmlWriter.WriteAttributeString(
                        AtomConstants.MediaLinkEntryContentSourceAttributeName,
                        this.atomEntryAndFeedSerializer.UriToUrlAttributeValue(mediaResource.ReadLink));

                    // </content>
                    this.atomOutputContext.XmlWriter.WriteEndElement();
                }

                this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero();
                this.atomEntryAndFeedSerializer.WriteProperties(
                    entryType,
                    propertiesValueCache.EntryProperties,
                    false /* isWritingCollection */,
                    this.atomEntryAndFeedSerializer.WriteEntryPropertiesStart,
                    this.atomEntryAndFeedSerializer.WriteEntryPropertiesEnd,
                    this.DuplicatePropertyNamesChecker,
                    propertiesValueCache,
                    rootSourcePathSegment,
                    projectedProperties);
                this.atomEntryAndFeedSerializer.AssertRecursionDepthIsZero();
            }
        }
Esempio n. 5
0
        internal void WriteEntryMetadata(ODataEntry entry, ProjectedPropertiesAnnotation projectedProperties, IEdmEntityType entryEntityType, DuplicatePropertyNamesChecker duplicatePropertyNamesChecker)
        {
            base.JsonWriter.WriteName("__metadata");
            base.JsonWriter.StartObjectScope();
            string id = entry.Id;

            if (id != null)
            {
                base.JsonWriter.WriteName("id");
                base.JsonWriter.WriteValue(id);
            }
            Uri uri = entry.EditLink ?? entry.ReadLink;

            if (uri != null)
            {
                base.JsonWriter.WriteName("uri");
                base.JsonWriter.WriteValue(base.UriToAbsoluteUriString(uri));
            }
            string eTag = entry.ETag;

            if (eTag != null)
            {
                base.WriteETag("etag", eTag);
            }
            string typeName = entry.TypeName;
            SerializationTypeNameAnnotation annotation = entry.GetAnnotation <SerializationTypeNameAnnotation>();

            if (annotation != null)
            {
                typeName = annotation.TypeName;
            }
            if (typeName != null)
            {
                base.JsonWriter.WriteName("type");
                base.JsonWriter.WriteValue(typeName);
            }
            ODataStreamReferenceValue mediaResource = entry.MediaResource;

            if (mediaResource != null)
            {
                WriterValidationUtils.ValidateStreamReferenceValue(mediaResource, true);
                base.WriteStreamReferenceValueContent(mediaResource);
            }
            IEnumerable <ODataAction> actions = entry.Actions;

            if (actions != null)
            {
                this.WriteOperations(actions.Cast <ODataOperation>(), true);
            }
            IEnumerable <ODataFunction> functions = entry.Functions;

            if (functions != null)
            {
                this.WriteOperations(functions.Cast <ODataOperation>(), false);
            }
            IEnumerable <ODataAssociationLink> associationLinks = entry.AssociationLinks;

            if (associationLinks != null)
            {
                bool flag = true;
                foreach (ODataAssociationLink link in associationLinks)
                {
                    ValidationUtils.ValidateAssociationLinkNotNull(link);
                    if (!projectedProperties.ShouldSkipProperty(link.Name))
                    {
                        if (flag)
                        {
                            base.JsonWriter.WriteName("properties");
                            base.JsonWriter.StartObjectScope();
                            flag = false;
                        }
                        base.ValidateAssociationLink(link, entryEntityType);
                        this.WriteAssociationLink(link, duplicatePropertyNamesChecker);
                    }
                }
                if (!flag)
                {
                    base.JsonWriter.EndObjectScope();
                }
            }
            base.JsonWriter.EndObjectScope();
        }
        /// <summary>
        /// Writes a name/value pair for a property.
        /// </summary>
        /// <param name="property">The property to write out.</param>
        /// <param name="owningType">The <see cref="IEdmStructuredType"/> of the entry or complex type containing the property (or null if not metadata is available).</param>
        /// <param name="allowStreamProperty">Should pass in true if we are writing a property of an ODataEntry instance, false otherwise.
        /// Named stream properties should only be defined on ODataEntry instances.</param>
        /// <param name="duplicatePropertyNamesChecker">The checker instance for duplicate property names.</param>
        /// <param name="projectedProperties">Set of projected properties, or null if all properties should be written.</param>
        private void WriteProperty(
            ODataProperty property,
            IEdmStructuredType owningType,
            bool allowStreamProperty,
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker,
            ProjectedPropertiesAnnotation projectedProperties)
        {
            DebugUtils.CheckNoExternalCallers();

            WriterValidationUtils.ValidatePropertyNotNull(property);

            string propertyName = property.Name;
            object value        = property.Value;

            if (projectedProperties.ShouldSkipProperty(propertyName))
            {
                return;
            }

            WriterValidationUtils.ValidatePropertyName(propertyName);
            duplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(property);
            IEdmProperty      edmProperty           = WriterValidationUtils.ValidatePropertyDefined(propertyName, owningType, this.MessageWriterSettings.UndeclaredPropertyBehaviorKinds);
            IEdmTypeReference propertyTypeReference = edmProperty == null ? null : edmProperty.Type;

            // If the property is of Geography or Geometry type or the value is of Geography or Geometry type
            // make sure to check that the version is 3.0 or above.
            if ((propertyTypeReference != null && propertyTypeReference.IsSpatial()) ||
                (propertyTypeReference == null && value is System.Spatial.ISpatial))
            {
                ODataVersionChecker.CheckSpatialValue(this.Version);
            }

            this.JsonWriter.WriteName(propertyName);
            if (value == null)
            {
                WriterValidationUtils.ValidateNullPropertyValue(propertyTypeReference, propertyName, this.MessageWriterSettings.WriterBehavior, this.Model);
                this.JsonWriter.WriteValue(null);
            }
            else
            {
                bool isOpenPropertyType = owningType != null && owningType.IsOpen && propertyTypeReference == null;
                if (isOpenPropertyType)
                {
                    ValidationUtils.ValidateOpenPropertyValue(propertyName, value, this.MessageWriterSettings.UndeclaredPropertyBehaviorKinds);
                }

                ODataComplexValue complexValue = value as ODataComplexValue;
                if (complexValue != null)
                {
                    this.WriteComplexValue(
                        complexValue,
                        propertyTypeReference,
                        isOpenPropertyType,
                        this.CreateDuplicatePropertyNamesChecker(),
                        /*collectionValidator*/ null);
                }
                else
                {
                    ODataCollectionValue collectionValue = value as ODataCollectionValue;
                    if (collectionValue != null)
                    {
                        ODataVersionChecker.CheckCollectionValueProperties(this.Version, propertyName);
                        this.WriteCollectionValue(
                            collectionValue,
                            propertyTypeReference,
                            isOpenPropertyType);
                    }
                    else
                    {
                        ODataStreamReferenceValue streamReferenceValue = value as ODataStreamReferenceValue;
                        if (streamReferenceValue != null)
                        {
                            if (!allowStreamProperty)
                            {
                                throw new ODataException(ODataErrorStrings.ODataWriter_StreamPropertiesMustBePropertiesOfODataEntry(propertyName));
                            }

                            Debug.Assert(owningType == null || owningType.IsODataEntityTypeKind(), "The metadata should not allow named stream properties to be defined on a non-entity type.");
                            WriterValidationUtils.ValidateStreamReferenceProperty(property, edmProperty, this.Version, this.WritingResponse);
                            WriterValidationUtils.ValidateStreamReferenceValue(streamReferenceValue, /*isDefaultStream*/ false);
                            this.WriteStreamReferenceValue(streamReferenceValue);
                        }
                        else
                        {
                            this.WritePrimitiveValue(value, /*collectionValidator*/ null, propertyTypeReference);
                        }
                    }
                }
            }
        }