/// <summary> /// Annotates the named stream with atom:link values. /// </summary> /// <param name="namedStream">The named stream to annotate.</param> /// <param name="href">The value of the atom:link's href property</param> /// <param name="rel">The value of the atom:link's rel property</param> /// <param name="type">The value of the atom:link's type property</param> /// <param name="hrefLang">The optional value of the atom:link's hrefLang property</param> /// <param name="title">The optional value of the atom:link's title property</param> /// <param name="length">The optional value of the atom:link's length property</param> /// <returns>The named stream with the annotations applied.</returns> public static NamedStreamInstance AtomNamedStreamLink(this NamedStreamInstance namedStream, string href, string rel, string type, string hrefLang = null, string title = null, string length = null) { ExceptionUtilities.CheckArgumentNotNull(namedStream, "namedStream"); // The Test OM representation for Named Streams does not allow individual annotation of the two links that it represents. // Thus, we special case Named Streams, and apply two annotations to represent ATOM link metadata - one for serialization and one for comparison. // This annotation will replace the standard serialization of the NamedStreamInstance with the link XElement. var xmlAnnotation = namedStream.Annotations.OfType <XmlPayloadElementRepresentationAnnotation>().SingleOrDefault(); if (xmlAnnotation == null) { xmlAnnotation = new XmlPayloadElementRepresentationAnnotation { XmlNodes = new XNode[0] }; namedStream.AddAnnotation(xmlAnnotation); } XElement linkElement = new XElement(TestAtomConstants.AtomXNamespace.GetName(TestAtomConstants.AtomLinkElementName)); AddXAttribute(linkElement, TestAtomConstants.AtomLinkHrefAttributeName, href); AddXAttribute(linkElement, TestAtomConstants.AtomLinkRelationAttributeName, rel); AddXAttribute(linkElement, TestAtomConstants.AtomLinkTypeAttributeName, type); AddXAttribute(linkElement, TestAtomConstants.AtomLinkHrefLangAttributeName, hrefLang); AddXAttribute(linkElement, TestAtomConstants.AtomLinkTitleAttributeName, title); AddXAttribute(linkElement, TestAtomConstants.AtomLinkLengthAttributeName, length); xmlAnnotation.XmlNodes = xmlAnnotation.XmlNodes.Union(new[] { linkElement }).ToArray(); // This annotation captures the link metadata values for comparison with test result. namedStream.AddAnnotation( new NamedStreamAtomLinkMetadataAnnotation { Href = href, HrefLang = hrefLang, Length = length, Relation = rel, Title = title, Type = type, }); return(namedStream); }
/// <summary> /// Deserialize a single link /// </summary> /// <param name="link">the xml representing the link</param> /// <returns>Either an expanded or deferred link</returns> private ODataPayloadElement DeserializeLink(XElement link) { if (link.Name == MetadataUri) { var result = new DeferredLink() { UriString = link.Attribute(AtomId).Value }; AddXmlBaseAnnotation(result, link); // add the element so that later validation can happen to validate the MetadataUri namespace is not used var xmlPayloadRep = new XmlPayloadElementRepresentationAnnotation() { XmlNodes = new XNode[] { link } }; result.Annotations.Add(xmlPayloadRep); return(result); } string hrefValue = null; XAttribute hrefAttribute = link.Attribute(Href); if (hrefAttribute != null) { if (string.IsNullOrEmpty(hrefAttribute.Value)) { // special case: navigation properties with null values are represented as empty href tags return(null); } hrefValue = hrefAttribute.Value; } // if the link has an inline element, assume it is expanded XElement inline = link.Element(MetadataInline); if (inline != null) { // deserialize the expanded element ExpandedLink expanded = new ExpandedLink() { UriString = hrefValue }; if (inline.HasElements) { expanded.ExpandedElement = this.ConvertToPayloadElement(inline.Elements().Single()); } this.AddLinkAttributes(expanded, link); return(expanded); } else { // otherwise it must be deferred DeferredLink deferred = new DeferredLink() { UriString = hrefValue }; this.AddLinkAttributes(deferred, link); return(deferred); } }