/// <summary> /// Writes the instance annotation start element. /// </summary> /// <param name="instanceAnnotation">The the instance annotation to write.</param> private void WriteInstanceAnnotationStart(AtomInstanceAnnotation instanceAnnotation) { // <m:annotation> this.XmlWriter.WriteStartElement(AtomConstants.ODataAnnotationElementName, AtomConstants.ODataMetadataNamespace); // <m:annotation term="instanceAnnotation.TermName"> this.XmlWriter.WriteAttributeString(AtomConstants.ODataAnnotationTermAttribute, string.Empty, instanceAnnotation.TermName); if (!string.IsNullOrEmpty(instanceAnnotation.Target)) { // <m:annotation term="termName" target="instanceAnnotation.Target"> this.XmlWriter.WriteAttributeString(AtomConstants.ODataAnnotationTargetAttribute, string.Empty, instanceAnnotation.Target); } }
/// <summary> /// Attempts to read the current element as an annotation element. /// </summary> /// <param name="annotation">If this method returned true, this is the instance annotation information from the parsed element.</param> /// <returns>true if the element was an annotation element, false if it wasn't.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - The element to read. /// Post-Condition: XmlNodeType.EndElement - The end tag of the element (if the element was a non-empty annotation element). /// XmlNodeType.Element - The same element as the pre-condition if this method returned false, or an empty annotation element. /// </remarks> internal bool TryReadAnnotation(out AtomInstanceAnnotation annotation) { BufferingXmlReader xmlReader = this.inputContext.XmlReader; Debug.Assert(xmlReader != null, "xmlReader != null"); Debug.Assert(xmlReader.NodeType == XmlNodeType.Element, "xmlReader must be positioned on an Element"); annotation = null; if (this.propertyAndValueDeserializer.MessageReaderSettings.ShouldIncludeAnnotation != null && xmlReader.NamespaceEquals(this.odataMetadataNamespace) && xmlReader.LocalNameEquals(this.attributeElementName)) { annotation = AtomInstanceAnnotation.CreateFrom(this.inputContext, this.propertyAndValueDeserializer); } return annotation != null; }
/// <summary> /// Attempts to read the current element as an annotation element. /// </summary> /// <param name="annotation">If this method returned true, this is the instance annotation information from the parsed element.</param> /// <returns>true if the element was an annotation element, false if it wasn't.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - The element to read. /// Post-Condition: XmlNodeType.EndElement - The end tag of the element (if the element was a non-empty annotation element). /// XmlNodeType.Element - The same element as the pre-condition if this method returned false, or an empty annotation element. /// </remarks> internal bool TryReadAnnotation(out AtomInstanceAnnotation annotation) { BufferingXmlReader xmlReader = this.inputContext.XmlReader; Debug.Assert(xmlReader != null, "xmlReader != null"); Debug.Assert(xmlReader.NodeType == XmlNodeType.Element, "xmlReader must be positioned on an Element"); annotation = null; if (this.propertyAndValueDeserializer.MessageReaderSettings.ShouldIncludeAnnotation != null && xmlReader.NamespaceEquals(this.odataMetadataNamespace) && xmlReader.LocalNameEquals(this.attributeElementName)) { annotation = AtomInstanceAnnotation.CreateFrom(this.inputContext, this.propertyAndValueDeserializer); } return(annotation != null); }
/// <summary> /// Writes the value of a primitive instance annotation. /// </summary> /// <param name="primitiveValue">The primitive value to write.</param> /// <param name="expectedTypeReference">The expected type of the annotation from the metadata.</param> private void WritePrimitiveInstanceAnnotationValue(ODataPrimitiveValue primitiveValue, IEdmTypeReference expectedTypeReference) { object clrValue = primitiveValue.Value; IEdmPrimitiveTypeReference primitiveTypeReference = EdmLibraryExtensions.GetPrimitiveTypeReference(clrValue.GetType()); string attributeValueNotationName = AtomInstanceAnnotation.LookupAttributeValueNotationNameByEdmTypeKind(primitiveTypeReference.PrimitiveKind()); // Some primitive values can be specified more concisely via an attribute rather than in the content of the xml element. This is called "attribute value notation". // If we're writing a type that supports this, then we always prefer attribute value notation over writing the value in the element content. if (attributeValueNotationName != null) { if (expectedTypeReference != null) { ValidationUtils.ValidateIsExpectedPrimitiveType(primitiveValue.Value, primitiveTypeReference, expectedTypeReference); } this.XmlWriter.WriteAttributeString(attributeValueNotationName, AtomValueUtils.ConvertPrimitiveToString(clrValue)); } else { this.WritePrimitiveValue(clrValue, /*collectionValidator*/ null, expectedTypeReference, primitiveValue.GetAnnotation <SerializationTypeNameAnnotation>()); } }
/// <summary> /// Writes a single instance annotation in ATOM format. /// </summary> /// <param name="instanceAnnotation">The instance annotation to write.</param> internal void WriteInstanceAnnotation(AtomInstanceAnnotation instanceAnnotation) { Debug.Assert(instanceAnnotation != null, "instanceAnnotation != null"); Debug.Assert(!string.IsNullOrEmpty(instanceAnnotation.TermName), "!string.IsNullOrEmpty(instanceAnnotation.TermName)"); if (this.MessageWriterSettings.ShouldSkipAnnotation(instanceAnnotation.TermName)) { return; } IEdmTypeReference expectedType = MetadataUtils.LookupTypeOfValueTerm(instanceAnnotation.TermName, this.Model); this.WriteInstanceAnnotationStart(instanceAnnotation); ODataPrimitiveValue primitiveValue = instanceAnnotation.Value as ODataPrimitiveValue; if (primitiveValue != null) { this.WritePrimitiveInstanceAnnotationValue(primitiveValue, expectedType); } else { ODataComplexValue complexValue = instanceAnnotation.Value as ODataComplexValue; if (complexValue != null) { this.WriteComplexValue( complexValue, expectedType, /*isOpenPropertyType*/ false, /*isWritingCollection*/ false, /*beforeValueAction*/ null, /*afterValueAction*/ null, this.CreateDuplicatePropertyNamesChecker(), /*collectionValidator*/ null, /*projectedProperties*/ null); } else { ODataCollectionValue collectionValue = instanceAnnotation.Value as ODataCollectionValue; if (collectionValue != null) { this.WriteCollectionValue( collectionValue, expectedType, /*isOpenPropertyType*/ false, /*isWritingCollection*/ false); } else { // Note that the ODataInstanceAnnotation constructor validates that the value is never an ODataStreamReferenceValue Debug.Assert(instanceAnnotation.Value is ODataNullValue, "instanceAnnotation.Value is ODataNullValue"); if (expectedType != null && !expectedType.IsNullable) { throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueSerializer_NullValueNotAllowedForInstanceAnnotation(instanceAnnotation.TermName, expectedType.FullName())); } this.WriteNullAttribute(); } } } this.WriteInstanceAnnotationEnd(); }
/// <summary> /// Writes the collection of <see cref="ODataInstanceAnnotation"/> to the ATOM payload. /// </summary> /// <param name="instanceAnnotations">The collection of <see cref="ODataInstanceAnnotation"/> to write.</param> /// <param name="tracker">Helper class to track if an annotation has been writen.</param> private void WriteInstanceAnnotations(IEnumerable <ODataInstanceAnnotation> instanceAnnotations, InstanceAnnotationWriteTracker tracker) { IEnumerable <AtomInstanceAnnotation> atomInstanceAnnotations = instanceAnnotations.Select(instanceAnnotation => AtomInstanceAnnotation.CreateFrom(instanceAnnotation, /*target*/ null)); this.atomEntryAndFeedSerializer.WriteInstanceAnnotations(atomInstanceAnnotations, tracker); }