Esempio n. 1
0
        private void WriteEntry(ODataWriter writer, Lazy <ODataReader> lazyReader, ODataResource entry)
        {
            this.WriteStart(writer, entry);
            var annotation = entry.GetAnnotation <ODataEntryNavigationLinksObjectModelAnnotation>();
            ODataNestedResourceInfo navLink = null;

            if (annotation != null)
            {
                for (int i = 0; i < annotation.Count; ++i)
                {
                    bool found = annotation.TryGetNavigationLinkAt(i, out navLink);
                    ExceptionUtilities.Assert(found, "Navigation links should be ordered sequentially for writing");
                    this.WriteNavigationLink(writer, lazyReader, navLink);
                }
            }

            this.WriteEnd(writer, ODataReaderState.ResourceEnd);
            this.Read(lazyReader);
        }
Esempio n. 2
0
        private void WriteAnnotationOnExpandedEntryInExpandedFeed(IEdmNavigationSource navigationSource, string expectedPayload, ODataFormat format)
        {
            Action <ODataWriter> action = (odataWriter) =>
            {
                var entryToWrite = new ODataResource {
                    Properties = new[] { new ODataProperty {
                                             Name = "ID", Value = 1
                                         } }
                };
                odataWriter.WriteStart(entryToWrite);

                ODataNestedResourceInfo navLink = new ODataNestedResourceInfo {
                    Name = "ResourceSetNavigationProperty", IsCollection = true
                };

                odataWriter.WriteStart(navLink);

                var feedToWrite = new ODataResourceSet {
                    Id = new Uri("urn:feedId")
                };
                odataWriter.WriteStart(feedToWrite);


                entryToWrite = new ODataResource {
                    Properties = new[] { new ODataProperty {
                                             Name = "ID", Value = 1
                                         } }
                };
                entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.StartAnnotation", PrimitiveValue1));
                entryToWrite.ETag = "ETag";
                odataWriter.WriteStart(entryToWrite);
                entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.EndAnnotation", PrimitiveValue1));
                odataWriter.WriteEnd();

                odataWriter.WriteEnd();

                odataWriter.WriteEnd();
                odataWriter.WriteEnd();
            };

            this.WriteAnnotationsAndValidatePayload(action, navigationSource, format, expectedPayload, request: false, createFeedWriter: false);
            this.WriteAnnotationsAndValidatePayload(action, navigationSource, format, expectedPayload, request: true, createFeedWriter: false);
        }
        public void ReadingSingleNavigationProppertyWithAllowedTypeAsNavigationPropertyTypeWithOrWithoutDerivedTypeConstraintWorks()
        {
            // Add a <NavigationProperty Name="FriendCustomer" Type="NS.Customer" />
            var navigationProperty = this.edmCustomerType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Target             = this.edmCustomerType,
                TargetMultiplicity = EdmMultiplicity.One,
                Name = "FriendCustomer"
            });

            Action <Stack <ODataItem> > verifyItems = (ms) =>
            {
                Assert.NotNull(ms);
                Assert.Equal(4, ms.Count);
                ODataResource resource = Assert.IsType <ODataResource>(ms.Pop()); // top level resource (id=7)
                Assert.Equal(7, resource.Properties.Single().Value);

                ODataNestedResourceInfo nestedLink = Assert.IsType <ODataNestedResourceInfo>(ms.Pop()); // FriendCustomer Navigation Link
                Assert.Equal(new Uri("http://example.com/Customers(7)/FriendCustomer"), nestedLink.Url);
                Assert.Equal("FriendCustomer", nestedLink.Name);

                resource = Assert.IsType <ODataResource>(ms.Pop()); // nested resource (id=8)
                Assert.Equal(8, resource.Properties.Single().Value);
                Assert.Equal("NS.VipCustomer", resource.TypeName);

                ODataNestedResourceInfo nestedResourceInfo = Assert.IsType <ODataNestedResourceInfo>(ms.Pop()); // FriendCustomer Nested resource info
                Assert.Throws <ODataException>(() => nestedResourceInfo.Url);
                Assert.Equal("FriendCustomer", nestedResourceInfo.Name);
            };

            string payload = "{\"@odata.context\":\"http://example.com/$metadata#Customers/$entity\",\"Id\":7,\"FriendCustomer\":{\"@odata.type\":\"#NS.VipCustomer\",\"Id\":8}}";

            // Navigation property doesn't have the derived type constraint.
            var items = ReadEntityPayload(payload, this.edmModel, this.edmCustomers, this.edmCustomerType);

            verifyItems(items);

            // Navigation property has the derived type constraint.
            SetDerivedTypeAnnotation(this.edmModel, navigationProperty, "NS.VipCustomer");

            items = ReadEntityPayload(payload, this.edmModel, this.edmCustomers, this.edmCustomerType);
            verifyItems(items);
        }
Esempio n. 4
0
        /// <summary>
        /// Adds a navigation link.
        /// </summary>
        /// <param name="link">The link.</param>
        public void AddNestedResourceInfo(ODataNestedResourceInfo link)
        {
            if (this.IsTracking)
            {
                this.EntityDescriptor.AddNestedResourceInfo(link.Name, link.Url);
                Uri associationLinkUrl = link.AssociationLinkUrl;
                if (associationLinkUrl != null)
                {
                    this.EntityDescriptor.AddAssociationLink(link.Name, associationLinkUrl);
                }
            }

            if (this.navigationLinks == ODataMaterializer.EmptyLinks)
            {
                this.navigationLinks = new List <ODataNestedResourceInfo>();
            }

            this.navigationLinks.Add(link);
        }
Esempio n. 5
0
        /// <summary>
        /// Visits a navigation link item.
        /// </summary>
        /// <param name="navigationLink">The navigation link to visit.</param>
        protected virtual void VisitNavigationLink(ODataNestedResourceInfo navigationLink)
        {
            object expandedContent;

            if (navigationLink.TryGetExpandedContent(out expandedContent) && expandedContent != null)
            {
                List <ODataItem> items = expandedContent as List <ODataItem>;
                if (items != null)
                {
                    foreach (ODataItem item in items)
                    {
                        this.Visit(item);
                    }
                }
                else
                {
                    this.Visit(expandedContent);
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Creates a nested resource info for a singleton entity reference link.
        /// </summary>
        /// <param name="nestedResourceInfo">The nested resource info to report.</param>
        /// <param name="navigationProperty">The navigation property for which the link will be reported.</param>
        /// <param name="entityReferenceLink">The entity reference link for the nested resource info to report.</param>
        /// <param name="isExpanded">true if the nested resource info is expanded.</param>
        /// <returns>The nested resource info created.</returns>
        internal static ODataJsonLightReaderNestedResourceInfo CreateSingletonEntityReferenceLinkInfo(
            ODataNestedResourceInfo nestedResourceInfo,
            IEdmNavigationProperty navigationProperty,
            ODataEntityReferenceLink entityReferenceLink,
            bool isExpanded)
        {
            Debug.Assert(nestedResourceInfo != null, "nestedResourceInfo != null");
            Debug.Assert(nestedResourceInfo.IsCollection == false, "Singleton entity reference can only be reported for a singleton navigation links.");
            Debug.Assert(navigationProperty != null, "navigationProperty != null");

            ODataJsonLightReaderNestedResourceInfo readerNestedResourceInfo = new ODataJsonLightReaderNestedResourceInfo(nestedResourceInfo, navigationProperty, isExpanded);

            if (entityReferenceLink != null)
            {
                readerNestedResourceInfo.entityReferenceLinks = new LinkedList <ODataEntityReferenceLink>();
                readerNestedResourceInfo.entityReferenceLinks.AddFirst(entityReferenceLink);
            }

            return(readerNestedResourceInfo);
        }
Esempio n. 7
0
        private void WriteComplexProperties(IEnumerable <IEdmStructuralProperty> complexProperties,
                                            ResourceContext resourceContext, ODataWriter writer)
        {
            Contract.Assert(complexProperties != null);
            Contract.Assert(resourceContext != null);
            Contract.Assert(writer != null);

            foreach (IEdmStructuralProperty complexProperty in complexProperties)
            {
                ODataNestedResourceInfo nestedResourceInfo = new ODataNestedResourceInfo
                {
                    IsCollection = complexProperty.Type.IsCollection(),
                    Name         = complexProperty.Name
                };

                writer.WriteStart(nestedResourceInfo);
                WriteComplexAndExpandedNavigationProperty(complexProperty, null, resourceContext, writer);
                writer.WriteEnd();
            }
        }
        private void WriteAnnotationAtEndExpandedFeedShouldFail(ODataFormat format)
        {
            Action <ODataWriter> action = (odataWriter) =>
            {
                var entryToWrite = new ODataResource {
                    Properties = new[] { new ODataProperty {
                                             Name = "ID", Value = 1
                                         } }
                };
                odataWriter.WriteStart(entryToWrite);

                ODataNestedResourceInfo navLink = new ODataNestedResourceInfo {
                    Name = "ResourceSetNavigationProperty", Url = new Uri("http://service/navLink", UriKind.RelativeOrAbsolute), IsCollection = true
                };
                odataWriter.WriteStart(navLink);

                var feedToWrite = new ODataResourceSet {
                    Id = new Uri("urn:feedId")
                };
                odataWriter.WriteStart(feedToWrite);

                feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("custom.StartFeedAnnotation", PrimitiveValue1));
                odataWriter.WriteEnd();
            };

            Action testResponse = () => this.WriteAnnotationsAndValidatePayload(action, EntitySet, format, null, request: false, createFeedWriter: false);

            testResponse.Throws <ODataException>(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedResourceSet);

            Action testResponseOfSingleton = () => this.WriteAnnotationsAndValidatePayload(action, Singleton, format, null, request: false, createFeedWriter: false);

            testResponseOfSingleton.Throws <ODataException>(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedResourceSet);

            Action testRequest = () => this.WriteAnnotationsAndValidatePayload(action, EntitySet, format, null, request: true, createFeedWriter: false);

            testRequest.Throws <ODataException>(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedResourceSet);

            Action testRequestOfSingleton = () => this.WriteAnnotationsAndValidatePayload(action, Singleton, format, null, request: true, createFeedWriter: false);

            testRequestOfSingleton.Throws <ODataException>(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedResourceSet);
        }
Esempio n. 9
0
            private void WriteNavigationNextLink(OeEntryFactory entryFactory, ExpandedNavigationSelectItem item, Object value)
            {
                var segment      = (NavigationPropertySegment)item.PathToNavigationProperty.LastSegment;
                var resourceInfo = new ODataNestedResourceInfo()
                {
                    IsCollection = true,
                    Name         = segment.NavigationProperty.Name
                };

                _writer.WriteStart(resourceInfo);

                var resourceSet = new ODataResourceSet()
                {
                    NextPageLink = BuildNavigationNextPageLink(_queryContext.EdmModel, entryFactory, item, value)
                };

                _writer.WriteStart(resourceSet);
                _writer.WriteEnd();

                _writer.WriteEnd();
            }
Esempio n. 10
0
        public async Task WriteNavigationLinkMetadataAsync_WritesNavigationLinkMetadata()
        {
            var nestedResourceInfo = new ODataNestedResourceInfo
            {
                Name               = "BestSeller",
                Url                = new Uri($"{ServiceUri}/Categories(1)/BestSeller"),
                IsCollection       = false,
                AssociationLinkUrl = new Uri($"{ServiceUri}/Categories(1)/associationLink")
            };

            var result = await SetupJsonLightResourceSerializerAndRunTestAsync(
                (jsonLightResourceSerializer) =>
            {
                return(jsonLightResourceSerializer.WriteNavigationLinkMetadataAsync(
                           nestedResourceInfo,
                           new NullDuplicatePropertyNameChecker()));
            });

            Assert.Equal("{\"[email protected]\":\"http://tempuri.org/Categories(1)/associationLink\"," +
                         "\"[email protected]\":\"http://tempuri.org/Categories(1)/BestSeller\"", result);
        }
Esempio n. 11
0
        private async Task WriteNavigation(Db.IOeDbEnumerator dbEnumerator)
        {
            bool isCollection = dbEnumerator.EntryFactory.EdmNavigationProperty.Type.Definition is EdmCollectionType;
            var  resourceInfo = new ODataNestedResourceInfo()
            {
                IsCollection = isCollection,
                Name         = dbEnumerator.EntryFactory.EdmNavigationProperty.Name
            };
            await _writer.WriteStartAsync(resourceInfo).ConfigureAwait(false);

            if (isCollection)
            {
                await WriteNavigationCollection(dbEnumerator).ConfigureAwait(false);
            }
            else
            {
                await WriteNavigationSingle(dbEnumerator).ConfigureAwait(false);
            }

            await _writer.WriteEndAsync().ConfigureAwait(false);
        }
Esempio n. 12
0
            private void WriteNavigationNextLink(ODataResource parentEntry, ExpandedNavigationSelectItem item)
            {
                var segment      = (NavigationPropertySegment)item.PathToNavigationProperty.LastSegment;
                var resourceInfo = new ODataNestedResourceInfo()
                {
                    IsCollection = true,
                    Name         = segment.NavigationProperty.Name
                };

                Writer.WriteStart(resourceInfo);

                var resourceSet = new ODataResourceSet()
                {
                    NextPageLink = BuildNavigationNextPageLink(parentEntry, item)
                };

                Writer.WriteStart(resourceSet);
                Writer.WriteEnd();

                Writer.WriteEnd();
            }
        public void WritingSingleNavigationProppertyWithNotAllowedTypeWorksWithoutDerivedTypeConstraintButFailedWithDerivedTypeConstraint()
        {
            // Add a <NavigationProperty Name="FriendCustomer" Type="NS.Customer" />
            var navigationProperty = this.edmCustomerType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Target             = this.edmCustomerType,
                TargetMultiplicity = EdmMultiplicity.One,
                Name = "FriendCustomer"
            });

            ODataNestedResourceInfo nestedResourceInfo = new ODataNestedResourceInfo
            {
                Name         = "FriendCustomer",
                IsCollection = false
            };

            Action <ODataMessageWriter> writeNavigationPropertyAction = (messageWriter) =>
            {
                ODataWriter writer = messageWriter.CreateODataResourceWriter(this.edmCustomers, this.edmCustomerType); // entityset
                writer.WriteStart(this.odataCustomerResource);
                writer.WriteStart(nestedResourceInfo);
                writer.WriteStart(this.odataNormalResource); // Normal customer
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
            };

            // Navigation property doesn't have the derived type constraint.
            string actual = GetWriterOutput(this.edmModel, writeNavigationPropertyAction);

            Assert.Contains("#Customers/$entity\",\"Id\":7,\"FriendCustomer\":{\"@odata.type\":\"#NS.NormalCustomer\",\"Id\":9", actual);

            // Negative test case --Navigation property has the derived type constraint.
            SetDerivedTypeAnnotation(this.edmModel, navigationProperty, "NS.VipCustomer");

            Action test      = () => GetWriterOutput(this.edmModel, writeNavigationPropertyAction);
            var    exception = Assert.Throws <ODataException>(test);

            Assert.Equal(Strings.WriterValidationUtils_ValueTypeNotAllowedInDerivedTypeConstraint("NS.NormalCustomer", "property", "FriendCustomer"), exception.Message);
        }
Esempio n. 14
0
        private Expression Translate(NavigationPropertySegment segment, bool?countOption)
        {
            IEdmNavigationProperty navigationEdmProperty = segment.NavigationProperty;
            var collectionType = navigationEdmProperty.Type.Definition as IEdmCollectionType;

            var resourceInfo = new ODataNestedResourceInfo()
            {
                IsCollection = collectionType != null,
                Name         = navigationEdmProperty.Name
            };

            var entitySet = (IEdmEntitySet)segment.NavigationSource;

            if (entitySet == null)
            {
                IEdmType entityType;
                if (collectionType == null)
                {
                    entityType = navigationEdmProperty.Type.Definition;
                }
                else
                {
                    entityType = collectionType.ElementType.Definition;
                }
                foreach (IEdmEntitySet element in _model.EntityContainer.Elements)
                {
                    if (element.EntityType() == entityType)
                    {
                        entitySet = element;
                        break;
                    }
                }
            }
            _selectItemInfo = new SelectItemInfo(entitySet, navigationEdmProperty, resourceInfo, countOption);

            PropertyInfo navigationClrProperty = _parameter.Type.GetTypeInfo().GetProperty(navigationEdmProperty.Name);

            return(Expression.MakeMemberAccess(_parameter, navigationClrProperty));
        }
Esempio n. 15
0
        private static void WriteNavigationLinks(ODataWriter writer, object element, Uri parentEntryUri, IEdmEntityType parentEntityType, IEdmModel model, ODataVersion targetVersion, IEnumerable <string> expandedNavigationProperties)
        {
            foreach (var navigationProperty in parentEntityType.NavigationProperties())
            {
                IEdmTypeReference propertyTypeReference = navigationProperty.Type;
                bool isCollection = navigationProperty.Type.IsCollection();

                var navigationLink = new ODataNestedResourceInfo
                {
                    Url          = new Uri(parentEntryUri, navigationProperty.Name),
                    IsCollection = isCollection,
                    Name         = navigationProperty.Name,
                };

                writer.WriteStart(navigationLink);

                if (expandedNavigationProperties.Contains(navigationProperty.Name))
                {
                    var propertyValue = DataContext.GetPropertyValue(element, navigationProperty.Name);

                    if (propertyValue != null)
                    {
                        var           propertyEntityType = propertyTypeReference.Definition as IEdmEntityType;
                        IEdmEntitySet targetEntitySet    = model.EntityContainer.EntitySets().Single(s => s.EntityType() == propertyEntityType);

                        if (isCollection)
                        {
                            WriteFeed(writer, propertyValue as IEnumerable, targetEntitySet, model, targetVersion, Enumerable.Empty <string>());
                        }
                        else
                        {
                            WriteEntry(writer, propertyValue, targetEntitySet, model, targetVersion, Enumerable.Empty <string>());
                        }
                    }
                }

                writer.WriteEnd();
            }
        }
        public void WritingSingleNavigationProppertyWithAllowedTypeAsNavigationPropertyTypeWithOrWithoutDerivedTypeConstraintWorks()
        {
            // Add a <NavigationProperty Name="FriendCustomer" Type="NS.Customer" />
            var navigationProperty = this.edmCustomerType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Target             = this.edmCustomerType,
                TargetMultiplicity = EdmMultiplicity.One,
                Name = "FriendCustomer"
            });

            ODataNestedResourceInfo nestedResourceInfo = new ODataNestedResourceInfo
            {
                Name         = "FriendCustomer",
                IsCollection = false
            };

            Action <ODataMessageWriter> writeNavigationPropertyAction = (messageWriter) =>
            {
                ODataWriter writer = messageWriter.CreateODataResourceWriter(this.edmMe, this.edmCustomerType); // singleton
                writer.WriteStart(this.odataCustomerResource);
                writer.WriteStart(nestedResourceInfo);
                writer.WriteStart(this.odataVipResource); // VipCustomer
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
            };

            // Navigation property doesn't have the derived type constraint.
            string actual = GetWriterOutput(this.edmModel, writeNavigationPropertyAction);

            Assert.Contains("#Me\",\"Id\":7,\"FriendCustomer\":{\"@odata.type\":\"#NS.VipCustomer\",\"Id\":8", actual);

            // Navigation property has the derived type constraint.
            SetDerivedTypeAnnotation(this.edmModel, navigationProperty, "NS.VipCustomer");

            string actualWithDerivedTypeConstraint = GetWriterOutput(this.edmModel, writeNavigationPropertyAction);

            Assert.Equal(actual, actualWithDerivedTypeConstraint);
        }
Esempio n. 17
0
        private void WriteExpandedNavigationProperties(
            IDictionary <IEdmNavigationProperty, SelectExpandClause> navigationPropertiesToExpand,
            ResourceContext resourceContext,
            ODataWriter writer)
        {
            Contract.Assert(navigationPropertiesToExpand != null);
            Contract.Assert(resourceContext != null);
            Contract.Assert(writer != null);

            foreach (KeyValuePair <IEdmNavigationProperty, SelectExpandClause> navPropertyToExpand in navigationPropertiesToExpand)
            {
                IEdmNavigationProperty navigationProperty = navPropertyToExpand.Key;

                ODataNestedResourceInfo navigationLink = CreateNavigationLink(navigationProperty, resourceContext);
                if (navigationLink != null)
                {
                    writer.WriteStart(navigationLink);
                    WriteComplexAndExpandedNavigationProperty(navPropertyToExpand.Key, navPropertyToExpand.Value, resourceContext, writer);
                    writer.WriteEnd();
                }
            }
        }
Esempio n. 18
0
        private async Task WriteDynamicComplexPropertiesAsync(ResourceContext resourceContext, ODataWriter writer)
        {
            Contract.Assert(resourceContext != null);
            Contract.Assert(resourceContext.EdmModel != null);

            if (resourceContext.DynamicComplexProperties == null)
            {
                return;
            }

            foreach (var dynamicComplexProperty in resourceContext.DynamicComplexProperties)
            {
                // If the dynamic property is "null", it should be treated ahead by creating an ODataProperty with ODataNullValue.
                // However, it's safety here to skip the null dynamic property.
                if (String.IsNullOrEmpty(dynamicComplexProperty.Key) || dynamicComplexProperty.Value == null)
                {
                    continue;
                }

                IEdmTypeReference edmTypeReference =
                    resourceContext.SerializerContext.GetEdmType(dynamicComplexProperty.Value,
                                                                 dynamicComplexProperty.Value.GetType());

                if (edmTypeReference.IsStructured() ||
                    (edmTypeReference.IsCollection() && edmTypeReference.AsCollection().ElementType().IsStructured()))
                {
                    ODataNestedResourceInfo nestedResourceInfo = new ODataNestedResourceInfo
                    {
                        IsCollection = edmTypeReference.IsCollection(),
                        Name         = dynamicComplexProperty.Key,
                    };

                    writer.WriteStart(nestedResourceInfo);
                    await WriteDynamicComplexPropertyAsync(dynamicComplexProperty.Value, edmTypeReference, resourceContext, writer);

                    writer.WriteEnd();
                }
            }
        }
        public void WritingMultipleComplexProppertyWithOrWithoutDerivedTypeConstraintWorks()
        {
            // Add a <Property Name="Locations" Type="Collection(NS.Address)" />
            var locationsProperty = this.edmCustomerType.AddStructuralProperty("Locations", new EdmCollectionTypeReference(new EdmCollectionType(new EdmComplexTypeReference(this.edmAddressType, false))));

            ODataNestedResourceInfo nestedResourceInfo = new ODataNestedResourceInfo
            {
                Name         = "Locations",
                IsCollection = true
            };

            Action <ODataMessageWriter> writePropertyAction = (messageWriter) =>
            {
                ODataWriter writer = messageWriter.CreateODataResourceWriter(this.edmCustomers, this.edmCustomerType); // entityset
                writer.WriteStart(this.odataCustomerResource);
                writer.WriteStart(nestedResourceInfo);
                writer.WriteStart(new ODataResourceSet());
                writer.WriteStart(this.odataCnAddressResource); // CnAddress
                writer.WriteEnd();
                writer.WriteStart(this.odataUsAddressResource); // UsAddress
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
            };

            // Structural property doesn't have the derived type constraint.
            string usAddressActual = GetWriterOutput(this.edmModel, writePropertyAction);

            Assert.Contains(",\"Id\":7,\"Locations\":[{\"@odata.type\":\"#NS.CnAddress\",\"Street\":\"Sha", usAddressActual);

            // Negative test case --Structural property has the derived type constraint.
            SetDerivedTypeAnnotation(this.edmModel, locationsProperty, "NS.CnAddress");

            Action test      = () => GetWriterOutput(this.edmModel, writePropertyAction);
            var    exception = Assert.Throws <ODataException>(test);

            Assert.Equal(Strings.WriterValidationUtils_ValueTypeNotAllowedInDerivedTypeConstraint("NS.UsAddress", "property", "Locations"), exception.Message);
        }
Esempio n. 20
0
        /// <summary>
        /// Returns all interesting payloads for a navigation link.
        /// </summary>
        /// <param name="testDescriptor">Test descriptor which will end up writing a single navigation link.</param>
        /// <returns>Enumeration of test descriptors which will include the original navigation link in some interesting scenarios.</returns>
        public static IEnumerable <PayloadWriterTestDescriptor <ODataItem> > NavigationLinkPayloads(PayloadWriterTestDescriptor <ODataItem> testDescriptor)
        {
            ODataNestedResourceInfo navigationLink = testDescriptor.PayloadItems[0] as ODataNestedResourceInfo;

            Debug.Assert(navigationLink != null, "Link payload expected.");

            var payloadCases = new WriterPayloadCase <ODataItem>[] {
                new WriterPayloadCase <ODataItem>()  // Single link on top-level entry
                {
                    GetPayloadItems       = () => new ODataItem[] { ObjectModelUtils.CreateDefaultEntry() }.Concat(testDescriptor.PayloadItems),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        return(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .Where(linkElement => linkElement.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(TestAtomConstants.ODataNavigationPropertiesRelatedLinkRelationPrefix))
                               .First());
                    },
                },

                // TODO: Add other interesting payloads for links - in expanded entry, in expanded feed
            };

            return(ApplyPayloadCases <ODataItem>(testDescriptor, payloadCases));
        }
        /// <summary>
        /// Writes the navigation link metadata.
        /// </summary>
        /// <param name="nestedResourceInfo">The navigation link to write the metadata for.</param>
        /// <param name="duplicatePropertyNameChecker">The DuplicatePropertyNameChecker to use.</param>
        internal void WriteNavigationLinkMetadata(ODataNestedResourceInfo nestedResourceInfo, IDuplicatePropertyNameChecker duplicatePropertyNameChecker)
        {
            Debug.Assert(nestedResourceInfo != null, "nestedResourceInfo != null");
            Debug.Assert(!string.IsNullOrEmpty(nestedResourceInfo.Name), "The nested resource info Name should have been validated by now.");
            Debug.Assert(duplicatePropertyNameChecker != null);

            Uri    navigationLinkUrl  = nestedResourceInfo.Url;
            string navigationLinkName = nestedResourceInfo.Name;
            Uri    associationLinkUrl = nestedResourceInfo.AssociationLinkUrl;

            if (associationLinkUrl != null)
            {
                duplicatePropertyNameChecker.ValidatePropertyOpenForAssociationLink(navigationLinkName);
                this.WriteAssociationLink(nestedResourceInfo.Name, associationLinkUrl);
            }

            if (navigationLinkUrl != null)
            {
                // The navigation link URL is a property annotation "[email protected]: 'url'"
                this.ODataAnnotationWriter.WritePropertyAnnotationName(navigationLinkName, ODataAnnotationNames.ODataNavigationLinkUrl);
                this.JsonWriter.WriteValue(this.UriToString(navigationLinkUrl));
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Creates the navigation link for the given navigation property.
        /// </summary>
        /// <param name="entityToSerialize">Entity that is currently being serialized.</param>
        /// <param name="navigationProperty">The metadata for the navigation property.</param>
        /// <returns>The navigation link for the given property.</returns>
        private ODataNestedResourceInfo GetNavigationLink(EntityToSerialize entityToSerialize, ResourceProperty navigationProperty)
        {
            Debug.Assert(entityToSerialize != null, "entityToSerialize != null");
            Debug.Assert(navigationProperty != null, "navigationProperty != null");

            string navLinkName = navigationProperty.Name;
            ODataNestedResourceInfo navLink = new ODataNestedResourceInfo
            {
                Name         = navLinkName,
                IsCollection = navigationProperty.Kind == ResourcePropertyKind.ResourceSetReference
            };

            // Always pass the relative uri to the ODatalib. For Json, they will convert the relative uri
            // into absolute uri using the BaseUri property on the ODataWriterSettings. For atom, ODataLib
            // will write the relative uri.
            this.PayloadMetadataPropertyManager.SetUrl(navLink, () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, navLinkName));

            if (this.Service.Configuration.DataServiceBehavior.IncludeAssociationLinksInResponse)
            {
                this.PayloadMetadataPropertyManager.SetAssociationLinkUrl(navLink, () => GetAssociationLinkUrl(entityToSerialize, navigationProperty));
            }

            return(navLink);
        }
Esempio n. 23
0
        private void ApplyInnerProperty(ODataResource innerResource, ComplexTypeWithChildComplexType parentInstance, TestMaterializerContext context = null)
        {
            context = context ?? new TestMaterializerContext();
            var resource = new ODataResource()
            {
                TypeName = "ComplexTypeWithChildComplexType", Properties = new ODataProperty[0]
            };

            var clientEdmModel    = new ClientEdmModel(ODataProtocolVersion.V4);
            var materializerEntry = MaterializerEntry.CreateEntry(resource, ODataFormat.Json, false, clientEdmModel);

            materializerEntry.ResolvedObject = parentInstance;
            ODataNestedResourceInfo innerComplexP = new ODataNestedResourceInfo()
            {
                Name = "InnerComplexProperty", IsCollection = false
            };

            MaterializerEntry innerMaterializerEntry;

            if (innerResource != null)
            {
                innerMaterializerEntry = MaterializerEntry.CreateEntry(innerResource, ODataFormat.Json, true, clientEdmModel);
            }
            else
            {
                innerMaterializerEntry = MaterializerEntry.CreateEmpty();
            }

            MaterializerNavigationLink.CreateLink(innerComplexP, innerMaterializerEntry);
            materializerEntry.AddNestedResourceInfo(innerComplexP);

            var policy = this.CreateEntryMaterializationPolicy(context);

            policy.EntityTrackingAdapter.TargetInstance = parentInstance;
            policy.Materialize(materializerEntry, typeof(ComplexTypeWithChildComplexType), true);
        }
Esempio n. 24
0
 public void CallBaseWriteStart(ODataNestedResourceInfo navigationLink)
 {
     this.odataWriter.WriteStart(navigationLink);
 }
Esempio n. 25
0
        public void MultiBindingOnComplexWriterTest()
        {
            ODataResource topEntity = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "TopEntity"
                                     } }
            };

            ODataNestedResourceInfo complex1Info = new ODataNestedResourceInfo()
            {
                Name = "complexProp1"
            };
            ODataResource complex1 = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "Prop1", Value = "complexProp1"
                                     } }
            };

            ODataNestedResourceInfo complex2Info = new ODataNestedResourceInfo()
            {
                Name = "complexProp2"
            };
            ODataResource complex2 = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "Prop1", Value = "complexProp2"
                                     } }
            };

            ODataNestedResourceInfo navOnComplexInfo = new ODataNestedResourceInfo()
            {
                Name = "CollectionOfNavOnComplex", IsCollection = true
            };

            ODataResourceSet resourceSet = new ODataResourceSet();
            ODataResource    navEntity1  = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "NavEntity1"
                                     } }
            };
            ODataResource navEntity2 = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "NavEntity2"
                                     } }
            };

            string actual = WriteJsonLightEntry(Model, EntitySet, (writer) =>
            {
                writer.WriteStart(topEntity);

                // complex1 and its navigation property
                writer.WriteStart(complex1Info);
                writer.WriteStart(complex1);
                writer.WriteStart(navOnComplexInfo);
                writer.WriteStart(resourceSet);
                writer.WriteStart(navEntity1);
                writer.WriteEnd();
                writer.WriteStart(navEntity2);
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();

                // complex2 and its navigation property
                writer.WriteStart(complex2Info);
                writer.WriteStart(complex2);
                writer.WriteStart(navOnComplexInfo);
                writer.WriteStart(resourceSet);
                writer.WriteStart(navEntity2);
                writer.WriteEnd();
                writer.WriteStart(navEntity1);
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();

                // end of top entity
                writer.WriteEnd();
            });

            Assert.Equal(complexPayload, actual);
        }
Esempio n. 26
0
        public void MultiBindingOnContainementWriterTest()
        {
            ODataResource topEntity = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "TopEntity"
                                     } }
            };

            ODataNestedResourceInfo contained1Info = new ODataNestedResourceInfo()
            {
                Name = "ContainedNav1", IsCollection = false
            };
            ODataResource contained1 = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "ContainedNav1"
                                     } }
            };

            ODataNestedResourceInfo contained2Info = new ODataNestedResourceInfo()
            {
                Name = "ContainedNav2", IsCollection = false
            };
            ODataResource contained2 = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "ContainedNav2"
                                     } }
            };

            ODataNestedResourceInfo navOnContainedInfo = new ODataNestedResourceInfo()
            {
                Name = "NavOnContained", IsCollection = false
            };

            ODataResource navEntity1 = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "NavEntity1"
                                     } }
            };
            ODataResource navEntity2 = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "NavEntity2"
                                     } }
            };

            string actual = WriteJsonLightEntry(Model, EntitySet, (writer) =>
            {
                writer.WriteStart(topEntity);

                // contained1 and its navigation property
                writer.WriteStart(contained1Info);
                writer.WriteStart(contained1);
                writer.WriteStart(navOnContainedInfo);
                writer.WriteStart(navEntity1);
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();

                // contained2 and its navigation property
                writer.WriteStart(contained2Info);
                writer.WriteStart(contained2);
                writer.WriteStart(navOnContainedInfo);
                writer.WriteStart(navEntity2);
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();

                // end of top entity
                writer.WriteEnd();
            });

            Assert.Equal(containmentPayload, actual);
        }
Esempio n. 27
0
        public void MultiBindingOnComplexWithTypeCastWriterReaderTest()
        {
            ODataResource topEntity = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "TopEntity"
                                     } }
            };

            ODataNestedResourceInfo complex1Info = new ODataNestedResourceInfo()
            {
                Name = "complexProp1"
            };
            ODataResource complex1 = new ODataResource()
            {
                TypeName   = "NS.DerivedComplexType",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "Prop1", Value = "complexProp1"
                    },
                    new ODataProperty {
                        Name = "DerivedProp", Value = "DerivedComplexProp"
                    }
                }
            };

            ODataNestedResourceInfo navOnComplexInfo = new ODataNestedResourceInfo()
            {
                Name = "CollectionOfNavOnComplex", IsCollection = true
            };

            ODataResourceSet resourceSet = new ODataResourceSet();
            ODataResource    navEntity1  = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "NavEntity1"
                                     } }
            };
            ODataResource navEntity2 = new ODataResource()
            {
                Properties = new[] { new ODataProperty {
                                         Name = "ID", Value = "NavEntity2"
                                     } }
            };

            // Writer
            string actual = WriteJsonLightEntry(Model, EntitySet, (writer) =>
            {
                writer.WriteStart(topEntity);

                // complex1 and its navigation property
                writer.WriteStart(complex1Info);
                writer.WriteStart(complex1);
                writer.WriteStart(navOnComplexInfo);
                writer.WriteStart(resourceSet);
                writer.WriteStart(navEntity1);
                writer.WriteEnd();
                writer.WriteStart(navEntity2);
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();
                writer.WriteEnd();

                // end of top entity
                writer.WriteEnd();
            });

            string expected = "{" +
                              "\"@odata.context\":\"http://host/$metadata#EntitySet/$entity\"," +
                              "\"ID\":\"TopEntity\"," +
                              "\"complexProp1\":{" +
                              "\"@odata.type\":\"#NS.DerivedComplexType\"," +
                              "\"Prop1\":\"complexProp1\"," +
                              "\"DerivedProp\":\"DerivedComplexProp\"," +
                              "\"CollectionOfNavOnComplex\":[" +
                              "{\"ID\":\"NavEntity1\"}," +
                              "{\"ID\":\"NavEntity2\"}]" +
                              "}}";

            Assert.Equal(expected, actual);

            // Reader
            var entryList = ReadPayload(expected, Model, EntitySet, EntityType);

            entryList[0].Id.Should().Be(new Uri("http://host/NavEntitySet1('NavEntity1')"));
            entryList[1].Id.Should().Be(new Uri("http://host/NavEntitySet1('NavEntity2')"));
            entryList[2].Id.Should().Be(null);
            entryList[2].TypeName.Should().Be("NS.DerivedComplexType");
            entryList[3].Id.Should().Be(new Uri("http://host/EntitySet('TopEntity')"));
        }
        /// <summary>
        /// Visits an item in the object model.
        /// </summary>
        /// <param name="objectModelItem">The item to visit.</param>
        public virtual T Visit(object objectModelItem)
        {
            ODataResourceSet feed = objectModelItem as ODataResourceSet;

            if (feed != null)
            {
                return(this.VisitFeed(feed));
            }

            ODataResource entry = objectModelItem as ODataResource;

            if (entry != null)
            {
                return(this.VisitEntry(entry));
            }

            ODataProperty property = objectModelItem as ODataProperty;

            if (property != null)
            {
                return(this.VisitProperty(property));
            }

            ODataNestedResourceInfo navigationLink = objectModelItem as ODataNestedResourceInfo;

            if (navigationLink != null)
            {
                return(this.VisitNavigationLink(navigationLink));
            }

            ODataResourceValue resourceValue = objectModelItem as ODataResourceValue;

            if (resourceValue != null)
            {
                return(this.VisitResourceValue(resourceValue));
            }

            ODataCollectionValue collection = objectModelItem as ODataCollectionValue;

            if (collection != null)
            {
                return(this.VisitCollectionValue(collection));
            }

            ODataStreamReferenceValue streamReferenceValue = objectModelItem as ODataStreamReferenceValue;

            if (streamReferenceValue != null)
            {
                return(this.VisitStreamReferenceValue(streamReferenceValue));
            }

            ODataCollectionStart collectionStart = objectModelItem as ODataCollectionStart;

            if (collectionStart != null)
            {
                return(this.VisitCollectionStart(collectionStart));
            }

            ODataServiceDocument serviceDocument = objectModelItem as ODataServiceDocument;

            if (serviceDocument != null)
            {
                return(this.VisitWorkspace(serviceDocument));
            }

            ODataEntitySetInfo entitySetInfo = objectModelItem as ODataEntitySetInfo;

            if (entitySetInfo != null)
            {
                return(this.VisitResourceCollection(entitySetInfo));
            }

            ODataError error = objectModelItem as ODataError;

            if (error != null)
            {
                return(this.VisitError(error));
            }

            ODataInnerError innerError = objectModelItem as ODataInnerError;

            if (innerError != null)
            {
                return(this.VisitInnerError(innerError));
            }

            ODataEntityReferenceLinks entityReferenceLinks = objectModelItem as ODataEntityReferenceLinks;

            if (entityReferenceLinks != null)
            {
                return(this.VisitEntityReferenceLinks(entityReferenceLinks));
            }

            ODataEntityReferenceLink entityReferenceLink = objectModelItem as ODataEntityReferenceLink;

            if (entityReferenceLink != null)
            {
                return(this.VisitEntityReferenceLink(entityReferenceLink));
            }

            ODataAction action = objectModelItem as ODataAction;

            if (action != null)
            {
                return(this.VisitODataOperation(action));
            }

            ODataFunction function = objectModelItem as ODataFunction;

            if (function != null)
            {
                return(this.VisitODataOperation(function));
            }

            ODataParameters parameters = objectModelItem as ODataParameters;

            if (parameters != null)
            {
                return(this.VisitParameters(parameters));
            }

            ODataBatch batch = objectModelItem as ODataBatch;

            if (batch != null)
            {
                return(this.VisitBatch(batch));
            }

            if (objectModelItem == null || objectModelItem is ODataPrimitiveValue || objectModelItem.GetType().IsValueType || objectModelItem is string ||
                objectModelItem is byte[] || objectModelItem is ISpatial)
            {
                return(this.VisitPrimitiveValue(objectModelItem));
            }

            if (objectModelItem is ODataUntypedValue)
            {
                object val = ODataObjectModelVisitor.ParseJsonToPrimitiveValue(
                    (objectModelItem as ODataUntypedValue).RawValue);
                return(this.VisitPrimitiveValue(val));
            }

            return(this.VisitUnsupportedValue(objectModelItem));
        }
 /// <summary>
 /// Visits a navigation link item.
 /// </summary>
 /// <param name="navigationLink">The navigation link to visit.</param>
 protected abstract T VisitNavigationLink(ODataNestedResourceInfo navigationLink);
Esempio n. 30
0
 /// <summary>
 /// Validates the specified <paramref name="property"/> matches
 /// the parsed <paramref name="link"/>.
 /// </summary>
 /// <param name="property">Property as understood by the type system.</param>
 /// <param name="link">Property as parsed.</param>
 internal static void ValidatePropertyMatch(ClientPropertyAnnotation property, ODataNestedResourceInfo link)
 {
     ValidatePropertyMatch(property, link, null, false /*performEntityCheck*/);
 }