/// <summary> /// Reads a navigation link in entry element. /// </summary> /// <param name="entryState">The reader entry state for the entry being read.</param> /// <param name="linkRelation">The value of the rel attribute of the link to read, unescaped parsed URI.</param> /// <param name="linkHRef">The value of the href attribute of the link to read.</param> /// <returns>A descriptor of a navigation link if a navigation link was found; null otherwise.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element atom:link - the start tag of the atom:link element to read. /// Post-Condition: XmlNodeType.Element atom:link - the start tag of the atom:link element - the reader doesn't move /// </remarks> private ODataAtomReaderNavigationLinkDescriptor TryReadNavigationLinkInEntry( IODataAtomReaderEntryState entryState, string linkRelation, string linkHRef) { Debug.Assert(linkRelation != null, "linkRelation != null"); this.XmlReader.AssertNotBuffering(); this.AssertXmlCondition(XmlNodeType.Element); Debug.Assert( this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace && this.XmlReader.LocalName == AtomConstants.AtomLinkElementName, "The XML reader must be on the atom:link element for this method to work."); string navigationLinkName = AtomUtils.GetNameFromAtomLinkRelationAttribute(linkRelation, AtomConstants.ODataNavigationPropertiesRelatedLinkRelationPrefix); if (string.IsNullOrEmpty(navigationLinkName)) { return null; } // Lookup the property in metadata // Note that we already verified that the navigation link name is not empty. IEdmNavigationProperty navigationProperty = ReaderValidationUtils.ValidateNavigationPropertyDefined(navigationLinkName, entryState.EntityType, this.MessageReaderSettings); // Navigation link ODataNavigationLink navigationLink = new ODataNavigationLink { Name = navigationLinkName }; // Get the type of the link string navigationLinkType = this.XmlReader.GetAttribute(this.AtomTypeAttributeName, this.EmptyNamespace); if (!string.IsNullOrEmpty(navigationLinkType)) { // Fast path for most common link types bool hasEntryType, hasFeedType; bool isExactMatch = AtomUtils.IsExactNavigationLinkTypeMatch(navigationLinkType, out hasEntryType, out hasFeedType); if (!isExactMatch) { // If the fast path did not work, we have to fully parse the media type. string mediaTypeName, mediaTypeCharset; IList<KeyValuePair<string, string>> contentTypeParameters = HttpUtils.ReadMimeType(navigationLinkType, out mediaTypeName, out mediaTypeCharset); if (!HttpUtils.CompareMediaTypeNames(mediaTypeName, MimeConstants.MimeApplicationAtomXml)) { return null; } string typeParameterValue = null; if (contentTypeParameters != null) { for (int contentTypeParameterIndex = 0; contentTypeParameterIndex < contentTypeParameters.Count; contentTypeParameterIndex++) { KeyValuePair<string, string> contentTypeParameter = contentTypeParameters[contentTypeParameterIndex]; if (HttpUtils.CompareMediaTypeParameterNames(MimeConstants.MimeTypeParameterName, contentTypeParameter.Key)) { typeParameterValue = contentTypeParameter.Value; break; } } } if (typeParameterValue != null) { if (string.Compare(typeParameterValue, MimeConstants.MimeTypeParameterValueEntry, StringComparison.OrdinalIgnoreCase) == 0) { hasEntryType = true; } else if (string.Compare(typeParameterValue, MimeConstants.MimeTypeParameterValueFeed, StringComparison.OrdinalIgnoreCase) == 0) { hasFeedType = true; } } } if (hasEntryType) { if (!this.UseClientFormatBehavior) { navigationLink.IsCollection = false; } } else if (hasFeedType) { navigationLink.IsCollection = true; } } if (linkHRef != null) { navigationLink.Url = this.ProcessUriFromPayload(linkHRef, this.XmlReader.XmlBaseUri); } this.XmlReader.MoveToElement(); // Read and store ATOM link metadata (captures extra info like lang, title) if ATOM metadata reading is turned on. AtomLinkMetadata atomLinkMetadata = this.EntryMetadataDeserializer.ReadAtomLinkElementInEntryContent(linkRelation, linkHRef); if (atomLinkMetadata != null) { navigationLink.SetAnnotation(atomLinkMetadata); } return new ODataAtomReaderNavigationLinkDescriptor(navigationLink, navigationProperty); }
public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, MaterializerEntry entry) { MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, entry); link.SetAnnotation<MaterializerNavigationLink>(annotation); return annotation; }
private ODataAtomReaderNavigationLinkDescriptor TryReadNavigationLinkInEntry(IODataAtomReaderEntryState entryState, string linkRelation, string linkHRef) { string nameFromAtomLinkRelationAttribute = AtomUtils.GetNameFromAtomLinkRelationAttribute(linkRelation, "http://schemas.microsoft.com/ado/2007/08/dataservices/related/"); if (string.IsNullOrEmpty(nameFromAtomLinkRelationAttribute)) { return null; } IEdmNavigationProperty navigationProperty = ReaderValidationUtils.ValidateNavigationPropertyDefined(nameFromAtomLinkRelationAttribute, entryState.EntityType, base.MessageReaderSettings); ODataNavigationLink navigationLink = new ODataNavigationLink { Name = nameFromAtomLinkRelationAttribute }; string attribute = base.XmlReader.GetAttribute(base.AtomTypeAttributeName, base.EmptyNamespace); if (!string.IsNullOrEmpty(attribute)) { bool flag; bool flag2; if (!AtomUtils.IsExactNavigationLinkTypeMatch(attribute, out flag, out flag2)) { string str3; string str4; IList<KeyValuePair<string, string>> list = HttpUtils.ReadMimeType(attribute, out str3, out str4); if (!HttpUtils.CompareMediaTypeNames(str3, "application/atom+xml")) { return null; } string strA = null; if (list != null) { for (int i = 0; i < list.Count; i++) { KeyValuePair<string, string> pair = list[i]; if (HttpUtils.CompareMediaTypeParameterNames("type", pair.Key)) { strA = pair.Value; break; } } } if (strA != null) { if (string.Compare(strA, "entry", StringComparison.OrdinalIgnoreCase) == 0) { flag = true; } else if (string.Compare(strA, "feed", StringComparison.OrdinalIgnoreCase) == 0) { flag2 = true; } } } if (flag) { if (!base.UseClientFormatBehavior) { navigationLink.IsCollection = false; } } else if (flag2) { navigationLink.IsCollection = true; } } if (linkHRef != null) { navigationLink.Url = base.ProcessUriFromPayload(linkHRef, base.XmlReader.XmlBaseUri); } base.XmlReader.MoveToElement(); AtomLinkMetadata annotation = this.EntryMetadataDeserializer.ReadAtomLinkElementInEntryContent(linkRelation, linkHRef); if (annotation != null) { navigationLink.SetAnnotation<AtomLinkMetadata>(annotation); } return new ODataAtomReaderNavigationLinkDescriptor(navigationLink, navigationProperty); }
public static MaterializerNavigationLink CreateLink(ODataNavigationLink link, ODataFeed feed) { MaterializerNavigationLink annotation = new MaterializerNavigationLink(link, feed); link.SetAnnotation<MaterializerNavigationLink>(annotation); return annotation; }