Ejemplo n.º 1
0
        /// <summary>Parses a link for the specified <paramref name="targetEntry"/>.</summary>
        /// <param name="targetEntry">Entry to update with link information.</param>
        private void ParseCurrentLink(AtomEntry targetEntry)
        {
            Debug.Assert(targetEntry != null, "targetEntry != null");
            Debug.Assert(
                this.reader.NodeType == XmlNodeType.Element,
                "this.reader.NodeType == XmlNodeType.Element -- otherwise we shouldn't try to parse a link");
            Debug.Assert(
                this.reader.LocalName == "link",
                "this.reader.LocalName == 'link' -- otherwise we shouldn't try to parse a link");

            string propertyName = null;

            string relation = this.reader.GetAttribute(XmlConstants.AtomLinkRelationAttributeName);
            if (relation == null)
            {
                return;
            }

            if ((relation == XmlConstants.AtomEditRelationAttributeValue ||
                XmlConstants.AtomEditRelationAttributeValue == UriUtil.GetNameFromAtomLinkRelationAttribute(relation, XmlConstants.IanaLinkRelationsNamespace))
                && targetEntry.EditLink == null)
            {
                // Only process the first link that has @rel='edit'.
                string href = this.reader.GetAttribute(XmlConstants.AtomHRefAttributeName);
                if (String.IsNullOrEmpty(href))
                {
                    throw Error.InvalidOperation(Strings.Context_MissingEditLinkInResponseBody);
                }

                targetEntry.EditLink = this.ProcessUriFromPayload(href);
            }
            else if ((relation == XmlConstants.AtomSelfRelationAttributeValue ||
                XmlConstants.AtomSelfRelationAttributeValue == UriUtil.GetNameFromAtomLinkRelationAttribute(relation, XmlConstants.IanaLinkRelationsNamespace))
                && targetEntry.QueryLink == null)
            {
                // Only process the first link that has @rel='self'.
                string href = this.reader.GetAttribute(XmlConstants.AtomHRefAttributeName);
                if (String.IsNullOrEmpty(href))
                {
                    throw Error.InvalidOperation(Strings.Context_MissingSelfLinkInResponseBody);
                }

                targetEntry.QueryLink = this.ProcessUriFromPayload(href);
            }
            else if ((relation == XmlConstants.AtomEditMediaRelationAttributeValue ||
                XmlConstants.AtomEditMediaRelationAttributeValue == UriUtil.GetNameFromAtomLinkRelationAttribute(relation, XmlConstants.IanaLinkRelationsNamespace))
                && targetEntry.MediaEditUri == null)
            {
                string href = this.reader.GetAttribute(XmlConstants.AtomHRefAttributeName);
                if (String.IsNullOrEmpty(href))
                {
                    throw Error.InvalidOperation(Strings.Context_MissingEditMediaLinkInResponseBody);
                }

                targetEntry.MediaEditUri = this.ProcessUriFromPayload(href);
                targetEntry.EntityDescriptor.StreamETag = this.reader.GetAttribute(XmlConstants.AtomETagAttributeName, XmlConstants.DataWebMetadataNamespace);
            }
            else if ((propertyName = UriUtil.GetNameFromAtomLinkRelationAttribute(relation, XmlConstants.DataWebRelatedNamespace)) != null)
            {
                #region Read the navigation link from the href attribute and handle expanded entities, if any
                bool isFeed = false;
                string propertyValueText = this.reader.GetAttribute(XmlConstants.AtomTypeAttributeName);
                if (!IsAllowedNavigationLinkType(propertyValueText, out isFeed))
                {
                    return;
                }

                // Get the link for the navigation property from the href attribute
                string href = this.reader.GetAttribute(XmlConstants.AtomHRefAttributeName);
                if (String.IsNullOrEmpty(href))
                {
                    throw Error.InvalidOperation(Strings.Context_MissingRelationshipLinkInResponseBody(propertyName));
                }

                // Add the link to the target entry so that we do use the link while querying the relationship
                Uri uri = this.ProcessUriFromPayload(href);
                targetEntry.AddNavigationLink(propertyName, uri, isFeed);

                if (!this.reader.IsEmptyElement)
                {
                    this.HandleExpandedNavigationProperties(targetEntry, propertyName, isFeed);
                }
                #endregion Read the navigation link from the href attribute and handle expanded entities, if any
            }
            else if ((propertyName = UriUtil.GetNameFromAtomLinkRelationAttribute(relation, XmlConstants.DataWebRelatedLinkNamespace)) != null)
            {
                string propertyValueText = this.reader.GetAttribute(XmlConstants.AtomTypeAttributeName);

                // check type="application/xml"
                if (!IsAllowedAssociationLinkType(propertyValueText))
                {
                    return;
                }

                // Get the related link for the navigation property from the href attribute
                string href = this.reader.GetAttribute(XmlConstants.AtomHRefAttributeName);
                if (String.IsNullOrEmpty(href))
                {
                    throw Error.InvalidOperation(Strings.Context_MissingRelationshipLinkInResponseBody(propertyName));
                }

                // Add the link to the target entry so that we do use the link while querying the association
                Uri uri = this.ProcessUriFromPayload(href);
                targetEntry.AddAssociationLink(propertyName, uri);
            }
            else if ((propertyName = UriUtil.GetNameFromAtomLinkRelationAttribute(relation, XmlConstants.DataWebMediaResourceEditNamespace)) != null)
            {
                this.ReadNamedStreamInfoFromLinkElement(targetEntry, propertyName, true/*editLink*/);
            }
            else if ((propertyName = UriUtil.GetNameFromAtomLinkRelationAttribute(relation, XmlConstants.DataWebMediaResourceNamespace)) != null)
            {
                this.ReadNamedStreamInfoFromLinkElement(targetEntry, propertyName, false/*editLink*/);
            }
        }