public void UrlToStringShouldThrowWithNoMetadataAndMetadataDocumentUriIsNotProvided()
        {
            var    stream           = new MemoryStream();
            var    serializer       = GetSerializer(stream, null, true, false);
            var    uri              = new Uri("TestUri", UriKind.Relative);
            Action uriToStrongError = () => serializer.UriToString(uri);

            uriToStrongError.Throws <ODataException>(Strings.ODataJsonLightSerializer_RelativeUriUsedWithoutMetadataDocumentUriOrMetadata(UriUtils.UriToString(uri)));
        }
Exemple #2
0
        /// <summary>
        /// Converts the given <paramref name="uri"/> Uri to a string.
        /// If the provided baseUri is not null and is a base Uri of the <paramref name="uri"/> Uri
        /// the method returns the string form of the relative Uri.
        /// </summary>
        /// <param name="uri">The Uri to convert.</param>
        /// <param name="failOnRelativeUriWithoutBaseUri">If set to true then this method will fail if the uri specified by <paramref name="uri"/> is relative
        /// and no base uri is specified.</param>
        /// <returns>The string form of the <paramref name="uri"/> Uri. If the Uri is absolute it returns the
        /// string form of the <paramref name="uri"/>. If the <paramref name="uri"/> Uri is not absolute
        /// it returns the original string of the Uri.</returns>
        internal string UriToUrlAttributeValue(Uri uri, bool failOnRelativeUriWithoutBaseUri)
        {
            Debug.Assert(uri != null, "uri != null");

            if (this.UrlResolver != null)
            {
                // The resolver returns 'null' if no custom resolution is desired.
                Uri resultUri = this.UrlResolver.ResolveUrl(this.MessageWriterSettings.PayloadBaseUri, uri);
                if (resultUri != null)
                {
                    return(UriUtils.UriToString(resultUri));
                }
            }

            if (!uri.IsAbsoluteUri)
            {
                // NOTE: the only URIs that are allowed to be relative (e.g., failOnRelativeUriWithoutBaseUri is false)
                //       are metadata URIs in operations; for such metadata URIs there is no base URI.
                if (this.MessageWriterSettings.PayloadBaseUri == null && failOnRelativeUriWithoutBaseUri)
                {
                    throw new ODataException(
                              ODataErrorStrings.ODataWriter_RelativeUriUsedWithoutBaseUriSpecified(UriUtils.UriToString(uri)));
                }

                uri = UriUtils.EnsureEscapedRelativeUri(uri);
            }

            return(UriUtils.UriToString(uri));
        }
        /// <summary>
        /// Resolves a type.
        /// </summary>
        /// <param name="typeName">The type name.</param>
        /// <param name="clientCustomTypeResolver">The function of client cuetom type resolver.</param>
        /// <param name="throwIfMetadataConflict">Whether to throw if a type specified in the ContextUri is not found in metadata.</param>
        /// <returns>The resolved Edm type.</returns>
        private ODataPayloadKind ResolveType(string typeName, Func <IEdmType, string, IEdmType> clientCustomTypeResolver, bool throwIfMetadataConflict)
        {
            string typeNameToResolve = EdmLibraryExtensions.GetCollectionItemTypeName(typeName) ?? typeName;
            bool   isCollection      = typeNameToResolve != typeName;

            EdmTypeKind typeKind;
            IEdmType    resolvedType = MetadataUtils.ResolveTypeNameForRead(this.model, /*expectedType*/ null, typeNameToResolve, clientCustomTypeResolver, out typeKind);

            if (resolvedType == null && !throwIfMetadataConflict)
            {
                string namespaceName;
                string name;
                TypeUtils.ParseQualifiedTypeName(typeName, out namespaceName, out name, out isCollection);
                resolvedType = new EdmUntypedStructuredType(namespaceName, name);
            }

            if (resolvedType == null ||
                resolvedType.TypeKind != EdmTypeKind.Primitive &&
                resolvedType.TypeKind != EdmTypeKind.Enum &&
                resolvedType.TypeKind != EdmTypeKind.Complex &&
                resolvedType.TypeKind != EdmTypeKind.Entity &&
                resolvedType.TypeKind != EdmTypeKind.TypeDefinition &&
                resolvedType.TypeKind != EdmTypeKind.Untyped)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidEntitySetNameOrTypeName(UriUtils.UriToString(this.parseResult.ContextUri), typeName));
            }

            if (resolvedType.TypeKind == EdmTypeKind.Entity || resolvedType.TypeKind == EdmTypeKind.Complex)
            {
                this.parseResult.EdmType = resolvedType;
                return(isCollection ? ODataPayloadKind.ResourceSet : ODataPayloadKind.Resource);
            }

            // For structured collection ,the EdmType is element type. for primitive collection, it is collection type
            resolvedType             = isCollection ? EdmLibraryExtensions.GetCollectionType(resolvedType.ToTypeReference(true /*nullable*/)) : resolvedType;
            this.parseResult.EdmType = resolvedType;
            return(isCollection ? ODataPayloadKind.Collection : ODataPayloadKind.Property);
        }
Exemple #4
0
        /// <summary>
        /// Returns the string representation of the URI
        /// </summary>
        /// <param name="uri">The uri to process.</param>
        /// <returns>Returns the string representation of the URI.</returns>
        internal string UriToString(Uri uri)
        {
            Debug.Assert(uri != null, "uri != null");

            // Get the metadataDocumentUri directly from MessageWriterSettings and not using ContextUriBuilder because in the case of getting the service document with nometadata
            // ContextUriBuilder returns null, but the metadataDocumentUri is needed to calculate Absolute Uris in the service document. In any other case jsonLightOutputContext.CreateContextUriBuilder() should be used.
            Uri metadataDocumentUri = this.jsonLightOutputContext.MessageWriterSettings.MetadataDocumentUri;

            Uri resultUri;

            if (this.jsonLightOutputContext.PayloadUriConverter != null)
            {
                // The resolver returns 'null' if no custom resolution is desired.
                resultUri = this.jsonLightOutputContext.PayloadUriConverter.ConvertPayloadUri(metadataDocumentUri, uri);
                if (resultUri != null)
                {
                    return(UriUtils.UriToString(resultUri));
                }
            }

            resultUri = uri;
            if (!resultUri.IsAbsoluteUri)
            {
                if (!this.allowRelativeUri)
                {
                    // TODO: Check if it is dead code to be removed.
                    if (metadataDocumentUri == null)
                    {
                        throw new ODataException(Strings.ODataJsonLightSerializer_RelativeUriUsedWithoutMetadataDocumentUriOrMetadata(UriUtils.UriToString(resultUri)));
                    }

                    resultUri = UriUtils.UriToAbsoluteUri(metadataDocumentUri, uri);
                }
                else
                {
                    resultUri = UriUtils.EnsureEscapedRelativeUri(resultUri);
                }
            }

            return(UriUtils.UriToString(resultUri));
        }
        private ODataPayloadKind ParseContextUriFragment(string fragment, Func <IEdmType, string, IEdmType> clientCustomTypeResolver, bool throwIfMetadataConflict, out bool isUndeclared)
        {
            bool           hasItemSelector = false;
            ODataDeltaKind kind            = ODataDeltaKind.None;

            isUndeclared = false;

            // Deal with /$entity
            if (fragment.EndsWith(ODataConstants.ContextUriFragmentItemSelector, StringComparison.Ordinal))
            {
                hasItemSelector = true;
                fragment        = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriFragmentItemSelector.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeltaResourceSet, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.ResourceSet;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeltaResourceSet.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeletedEntry, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.DeletedEntry;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeletedEntry.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeltaLink, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.Link;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeltaLink.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeletedLink, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.DeletedLink;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeletedLink.Length);
            }

            this.parseResult.DeltaKind = kind;

            // Deal with query option
            if (fragment.EndsWith(")", StringComparison.Ordinal))
            {
                int index = fragment.Length - 2;
                for (int rcount = 1; rcount > 0 && index > 0; --index)
                {
                    switch (fragment[index])
                    {
                    case '(':
                        rcount--;
                        break;

                    case ')':
                        rcount++;
                        break;
                    }
                }

                if (index == 0)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                string previous = fragment.Substring(0, index + 1);

                // Don't treat Collection(Edm.Type) as SelectExpand segment
                if (!previous.Equals("Collection"))
                {
                    string selectExpandStr = fragment.Substring(index + 2);
                    selectExpandStr = selectExpandStr.Substring(0, selectExpandStr.Length - 1);

                    // Do not treat Key as SelectExpand segment
                    if (KeyPattern.IsMatch(selectExpandStr))
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_LastSegmentIsKeySegment(UriUtils.UriToString(this.parseResult.ContextUri)));
                    }

                    this.parseResult.SelectQueryOption = ExtractSelectQueryOption(selectExpandStr);
                    fragment = previous;
                }
            }

            ODataPayloadKind detectedPayloadKind = ODataPayloadKind.Unsupported;
            EdmTypeResolver  edmTypeResolver     = new EdmTypeReaderResolver(this.model, clientCustomTypeResolver);

            if (!fragment.Contains(ODataConstants.UriSegmentSeparator) && !hasItemSelector && kind == ODataDeltaKind.None)
            {
                // Service document: no fragment
                if (fragment.Length == 0)
                {
                    detectedPayloadKind = ODataPayloadKind.ServiceDocument;
                }
                else if (fragment.Equals(ODataConstants.CollectionPrefix + "(" + ODataConstants.EntityReferenceSegmentName + ")"))
                {
                    detectedPayloadKind = ODataPayloadKind.EntityReferenceLinks;
                }
                else if (fragment.Equals(ODataConstants.EntityReferenceSegmentName))
                {
                    detectedPayloadKind = ODataPayloadKind.EntityReferenceLink;
                }
                else
                {
                    var foundNavigationSource = this.model.FindDeclaredNavigationSource(fragment);

                    if (foundNavigationSource != null)
                    {
                        // Resource Set: {schema.entity-container.entity-set} or Singleton: {schema.entity-container.singleton}
                        this.parseResult.NavigationSource = foundNavigationSource;
                        this.parseResult.EdmType          = edmTypeResolver.GetElementType(foundNavigationSource);
                        detectedPayloadKind = foundNavigationSource is IEdmSingleton ? ODataPayloadKind.Resource : ODataPayloadKind.ResourceSet;
                    }
                    else
                    {
                        // Property: {schema.type} or Collection({schema.type}) where schema.type is primitive or complex.
                        detectedPayloadKind = this.ResolveType(fragment, clientCustomTypeResolver, throwIfMetadataConflict);
                        Debug.Assert(
                            this.parseResult.EdmType.TypeKind == EdmTypeKind.Primitive || this.parseResult.EdmType.TypeKind == EdmTypeKind.Enum || this.parseResult.EdmType.TypeKind == EdmTypeKind.TypeDefinition || this.parseResult.EdmType.TypeKind == EdmTypeKind.Complex || this.parseResult.EdmType.TypeKind == EdmTypeKind.Collection || this.parseResult.EdmType.TypeKind == EdmTypeKind.Entity || this.parseResult.EdmType.TypeKind == EdmTypeKind.Untyped,
                            "The first context URI segment must be a set or a non-entity type.");
                    }
                }
            }
            else
            {
                Debug.Assert(this.parseResult.MetadataDocumentUri.IsAbsoluteUri, "this.parseResult.MetadataDocumentUri.IsAbsoluteUri");

                string metadataDocumentStr = UriUtils.UriToString(this.parseResult.MetadataDocumentUri);

                if (!metadataDocumentStr.EndsWith(ODataConstants.UriMetadataSegment, StringComparison.Ordinal))
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                Uri serviceRoot = new Uri(metadataDocumentStr.Substring(0, metadataDocumentStr.Length - ODataConstants.UriMetadataSegment.Length));

                ODataUriParser odataUriParser = new ODataUriParser(this.model, serviceRoot, new Uri(serviceRoot, fragment));

                ODataPath path;
                try
                {
                    path = odataUriParser.ParsePath();
                }
                catch (ODataException)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                if (path.Count == 0)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                this.parseResult.Path = path;

                parseResult.NavigationSource = path.NavigationSource();
                parseResult.EdmType          = path.LastSegment.EdmType;

                ODataPathSegment lastSegment = path.TrimEndingTypeSegment().LastSegment;
                if (lastSegment is EntitySetSegment || lastSegment is NavigationPropertySegment)
                {
                    if (kind != ODataDeltaKind.None)
                    {
                        detectedPayloadKind = ODataPayloadKind.Delta;
                    }
                    else
                    {
                        detectedPayloadKind = hasItemSelector ? ODataPayloadKind.Resource : ODataPayloadKind.ResourceSet;
                    }

                    if (this.parseResult.EdmType is IEdmCollectionType)
                    {
                        var collectionTypeReference = this.parseResult.EdmType.ToTypeReference().AsCollection();
                        if (collectionTypeReference != null)
                        {
                            this.parseResult.EdmType = collectionTypeReference.ElementType().Definition;
                        }
                    }
                }
                else if (lastSegment is SingletonSegment)
                {
                    detectedPayloadKind = ODataPayloadKind.Resource;
                }
                else if (path.IsIndividualProperty())
                {
                    isUndeclared        = path.IsUndeclared();
                    detectedPayloadKind = ODataPayloadKind.Property;
                    IEdmComplexType complexType = parseResult.EdmType as IEdmComplexType;
                    if (complexType != null)
                    {
                        detectedPayloadKind = ODataPayloadKind.Resource;
                    }
                    else
                    {
                        IEdmCollectionType collectionType = parseResult.EdmType as IEdmCollectionType;

                        if (collectionType != null)
                        {
                            if (collectionType.ElementType.IsComplex())
                            {
                                this.parseResult.EdmType = collectionType.ElementType.Definition;
                                detectedPayloadKind      = ODataPayloadKind.ResourceSet;
                            }
                            else
                            {
                                detectedPayloadKind = ODataPayloadKind.Collection;
                            }
                        }
                    }
                }
                else
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }
            }

            return(detectedPayloadKind);
        }
        /// <summary>
        /// Applies the model and validates the context URI against it.
        /// </summary>
        /// <param name="expectedPayloadKind">The payload kind we expect the context URI to conform to.</param>
        /// <param name="clientCustomTypeResolver">The function of client custom type resolver.</param>
        /// <param name="throwIfMetadataConflict">Whether to throw if a type specified in the ContextUri is not found in metadata.</param>
        private void ParseContextUri(ODataPayloadKind expectedPayloadKind, Func <IEdmType, string, IEdmType> clientCustomTypeResolver, bool throwIfMetadataConflict)
        {
            bool             isUndeclared;
            ODataPayloadKind detectedPayloadKind = this.ParseContextUriFragment(this.parseResult.Fragment, clientCustomTypeResolver, throwIfMetadataConflict, out isUndeclared);

            // unsupported payload kind indicates that this is during payload kind detection, so we should not fail.
            bool     detectedPayloadKindMatchesExpectation = detectedPayloadKind == expectedPayloadKind || expectedPayloadKind == ODataPayloadKind.Unsupported;
            IEdmType parseType = this.parseResult.EdmType;

            if (parseType != null && parseType.TypeKind == EdmTypeKind.Untyped)
            {
                if (string.Equals(parseType.FullTypeName(), ODataConstants.ContextUriFragmentUntyped, StringComparison.Ordinal))
                {
                    // Anything matches the built-in Edm.Untyped
                    this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection, ODataPayloadKind.Resource };
                    detectedPayloadKindMatchesExpectation = true;
                }
                else if (expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Resource)
                {
                    // If we created an untyped type because the name was not resolved it can match any single value
                    this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Property, ODataPayloadKind.Resource };
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (parseType != null && parseType.TypeKind == EdmTypeKind.Collection && ((IEdmCollectionType)parseType).ElementType.TypeKind() == EdmTypeKind.Untyped)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection };
                if (expectedPayloadKind == ODataPayloadKind.ResourceSet || expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Collection)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.ResourceSet && parseType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection };

                if (expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Collection)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource && parseType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Collection)
            {
                // If the detected payload kind is 'collection' it can always also be treated as a property.
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Collection, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Delta };
                if (expectedPayloadKind == ODataPayloadKind.Delta)
                {
                    this.parseResult.DeltaKind            = ODataDeltaKind.Resource;
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Property && isUndeclared &&
                     (expectedPayloadKind == ODataPayloadKind.Resource || expectedPayloadKind == ODataPayloadKind.ResourceSet))
            {
                // for undeclared, we don't know whether it is a resource/resource set or not.
                this.parseResult.DetectedPayloadKinds = new[] { expectedPayloadKind, ODataPayloadKind.Property };
                detectedPayloadKindMatchesExpectation = true;
            }
            else
            {
                this.parseResult.DetectedPayloadKinds = new[] { detectedPayloadKind };
            }

            // If the expected and detected payload kinds don't match and we are not running payload kind detection
            // right now (payloadKind == ODataPayloadKind.Unsupported) and we did not detect a collection kind for
            // an expected property kind (which is allowed), fail.
            if (!detectedPayloadKindMatchesExpectation)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind(UriUtils.UriToString(this.parseResult.ContextUri), expectedPayloadKind.ToString()));
            }

            // NOTE: we interpret an empty select query option to mean that nothing should be projected
            //       (whereas a missing select query option means everything should be projected).
            string selectQueryOption = this.parseResult.SelectQueryOption;

            if (selectQueryOption != null)
            {
                if (detectedPayloadKind != ODataPayloadKind.ResourceSet && detectedPayloadKind != ODataPayloadKind.Resource && detectedPayloadKind != ODataPayloadKind.Delta)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidPayloadKindWithSelectQueryOption(expectedPayloadKind.ToString()));
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Validates that a string is either a valid absolute URI, or (if it begins with '#') it is a valid URI fragment.
        /// </summary>
        /// <param name="metadataDocumentUri">The metadata document uri.</param>
        /// <param name="propertyName">The property name to validate.</param>
        internal static void ValidateMetadataReferencePropertyName(Uri metadataDocumentUri, string propertyName)
        {
            Debug.Assert(metadataDocumentUri != null, "metadataDocumentUri != null");
            Debug.Assert(metadataDocumentUri.IsAbsoluteUri, "metadataDocumentUri.IsAbsoluteUri");
            Debug.Assert(!String.IsNullOrEmpty(propertyName), "!string.IsNullOrEmpty(propertyName)");

            string uriStringToValidate = propertyName;

            // If it starts with a '#', validate that the rest of the string is a valid Uri fragment.
            if (propertyName[0] == ODataConstants.ContextUriFragmentIndicator)
            {
                // In order to use System.Uri to validate a fragement, we first prepend the metadataDocumentUri
                // so that it becomes an absolute URI which we can validate with Uri.IsWellFormedUriString.
                uriStringToValidate = UriUtils.UriToString(metadataDocumentUri) + UriUtils.EnsureEscapedFragment(propertyName);
            }

            if (!Uri.IsWellFormedUriString(uriStringToValidate, UriKind.Absolute) ||
                !ODataJsonLightUtils.IsMetadataReferenceProperty(propertyName) ||
                propertyName[propertyName.Length - 1] == ODataConstants.ContextUriFragmentIndicator)
            {
                throw new ODataException(Strings.ValidationUtils_InvalidMetadataReferenceProperty(propertyName));
            }

            if (IsOpenMetadataReferencePropertyName(metadataDocumentUri, propertyName))
            {
                throw new ODataException(Strings.ODataJsonLightValidationUtils_OpenMetadataReferencePropertyNotSupported(propertyName, UriUtils.UriToString(metadataDocumentUri)));
            }
        }
        /// <summary>
        /// Writes a set of links (Uris) in response to a $links query; includes optional count and next-page-link information.
        /// </summary>
        /// <param name="writer">The <see cref="XmlWriter"/> to write to.</param>
        /// <param name="links">The associated entity links to write.</param>
        internal static void WriteAssociatedEntityLinks(XmlWriter writer, ODataAssociatedEntityLinks links)
        {
            DebugUtils.CheckNoExternalCallers();

            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(links != null, "links != null");

            // <links> ...
            writer.WriteStartElement(string.Empty, AtomConstants.ODataLinksElementName, AtomConstants.ODataNamespace);

            // xmlns=
            writer.WriteAttributeString(AtomConstants.XmlnsNamespacePrefix, AtomConstants.ODataNamespace);

            if (links.InlineCount.HasValue)
            {
                // <m:count>
                WriteCount(writer, links.InlineCount.Value, true);
            }

            IEnumerable <ODataAssociatedEntityLink> associatedEntityLinks = links.Links;

            if (associatedEntityLinks != null)
            {
                foreach (ODataAssociatedEntityLink link in associatedEntityLinks)
                {
                    WriteAssociatedEntityLink(writer, link, false);
                }
            }

            if (links.NextLink != null)
            {
                // <d:next>
                writer.WriteElementString(string.Empty, AtomConstants.ODataNextLinkElementName, AtomConstants.ODataNamespace, UriUtils.UriToString(links.NextLink));
            }

            // </links>
            writer.WriteEndElement();
        }
Exemple #9
0
        /// <summary>
        /// Converts the given <paramref name="uri"/> Uri to a string.
        /// If the provided baseUri is not null and is a base Uri of the <paramref name="uri"/> Uri
        /// the method returns the string form of the relative Uri.
        /// </summary>
        /// <param name="uri">The Uri to convert.</param>
        /// <param name="baseUri">An optional base Uri</param>
        /// <returns>The string form of the <paramref name="uri"/> Uri. If the Uri is absolute and
        /// the <paramref name="baseUri"/> is the base Uri of the <paramref name="uri"/> Uri it returns a relative Uri;
        /// otherwise the string form of the absolute Uri. If the <paramref name="uri"/> Uri is not absolute
        /// it returns the original string of the Uri.</returns>
        internal static string ToUrlAttributeValue(this Uri uri, Uri baseUri)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(uri != null, "uri != null");

            if (baseUri == null)
            {
                if (!uri.IsAbsoluteUri)
                {
                    throw new ODataException(Strings.ODataWriter_RelativeUriUsedWithoutBaseUriSpecified(UriUtils.UriToString(uri)));
                }
            }
            else
            {
                if (uri.IsAbsoluteUri && UriUtils.UriInvariantInsensitiveIsBaseOf(baseUri, uri))
                {
                    uri = baseUri.MakeRelativeUri(uri);
                }
            }

            return(UriUtils.UriToString(uri));
        }