/// <summary> /// Write the metadata of a link in ATOM format /// </summary> /// <param name="linkMetadata">The link metadata to write.</param> /// <param name="etag">The (optional) ETag for a link.</param> internal void WriteAtomLinkAttributes(AtomLinkMetadata linkMetadata, string etag) { Debug.Assert(linkMetadata != null, "Link metadata must not be null."); string linkHref = linkMetadata.Href == null ? null : this.UriToUrlAttributeValue(linkMetadata.Href); this.WriteAtomLinkMetadataAttributes(linkMetadata.Relation, linkHref, linkMetadata.HrefLang, linkMetadata.Title, linkMetadata.MediaType, linkMetadata.Length); if (etag != null) { ODataAtomWriterUtils.WriteETag(this.XmlWriter, etag); } }
/// <summary> /// Start writing an entry. /// </summary> /// <param name="entry">The entry to write.</param> protected override void StartEntry(ODataEntry entry) { this.CheckAndWriteParentNavigationLinkStartForInlineElement(); Debug.Assert( this.ParentNavigationLink == null || !this.ParentNavigationLink.IsCollection.Value, "We should have already verified that the IsCollection matches the actual content of the link (feed/entry)."); if (entry == null) { Debug.Assert(this.ParentNavigationLink != null, "When entry == null, it has to be an expanded single entry navigation."); // this is a null expanded single entry and it is null, an empty <m:inline /> will be written. return; } // <entry> this.atomOutputContext.XmlWriter.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomEntryElementName, AtomConstants.AtomNamespace); if (this.IsTopLevel) { this.atomEntryAndFeedSerializer.WriteBaseUriAndDefaultNamespaceAttributes(); // Write metadata:context this.atomEntryAndFeedSerializer.TryWriteEntryContextUri(this.CurrentEntryScope.GetOrCreateTypeContext(this.atomOutputContext.Model, this.atomOutputContext.WritingResponse)); } string etag = entry.ETag; if (etag != null) { // TODO, ckerer: if this is a top-level entry also put the ETag into the headers. ODataAtomWriterUtils.WriteETag(this.atomOutputContext.XmlWriter, etag); } AtomEntryScope currentEntryScope = this.CurrentEntryScope; AtomEntryMetadata entryMetadata = entry.Atom(); // Write the id if it's available here. // If it's not available here we will try to write it at the end of the entry again. Uri entryId = entry.Id; bool isTransient = entry.IsTransient; if (entryId != null) { this.atomEntryAndFeedSerializer.WriteEntryId(entryId, isTransient); currentEntryScope.SetWrittenElement(AtomElement.Id); } // <category term="type" scheme="odatascheme"/> // If no type information is provided, don't include the category element for type at all // NOTE: the validation of the type name is done by the core writer. string typeName = this.atomOutputContext.TypeNameOracle.GetEntryTypeNameForWriting(entry); this.atomEntryAndFeedSerializer.WriteEntryTypeName(typeName, entryMetadata); // Write the edit link if it's available here. // If it's not available here we will try to write it at the end of the entry again. Uri editLink = entry.EditLink; if (editLink != null) { this.atomEntryAndFeedSerializer.WriteEntryEditLink(editLink, entryMetadata); currentEntryScope.SetWrittenElement(AtomElement.EditLink); } // Write the self link if it's available here. // If it's not available here we will try to write it at the end of the entry again. // If readlink is identical to editlink, don't write readlink. Uri readLink = entry.ReadLink; if (readLink != null) { if (readLink != editLink) { this.atomEntryAndFeedSerializer.WriteEntryReadLink(readLink, entryMetadata); } currentEntryScope.SetWrittenElement(AtomElement.ReadLink); } this.WriteInstanceAnnotations(entry.InstanceAnnotations, currentEntryScope.InstanceAnnotationWriteTracker); }