public void WritingSingleComplexProppertyWithAllowedTypeAsPropertyTypeWithOrWithoutDerivedTypeConstraintWorks()
        {
            // Add a <Property Name="Location" Type="NS.Address" />
            var locationProperty = this.edmCustomerType.AddStructuralProperty("Location", new EdmComplexTypeReference(this.edmAddressType, false));

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

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

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

            Assert.Contains("#Me\",\"Id\":7,\"Location\":{\"@odata.type\":\"#NS.UsAddress\",\"Street\":\"RedWay\",\"ZipCode\":98052}}", actual);

            // Structural property has the derived type constraint.
            SetDerivedTypeAnnotation(this.edmModel, locationProperty, "NS.UsAddress");

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

            Assert.Equal(actual, actualWithDerivedTypeConstraint);
        }
        private void TestAndMeasure(string propertyType)
        {
            var entry     = GenerateEntry(propertyType);
            var entitySet = Model.EntityContainer.FindEntitySet(propertyType);

            foreach (var iteration in Benchmark.Iterations)
            {
                // Reuse the same stream
                WriteStream.Seek(0, SeekOrigin.Begin);

                using (iteration.StartMeasurement())
                {
                    using (var messageWriter = ODataMessageHelper.CreateMessageWriter(WriteStream, Model, ODataMessageKind.Response, isFullValidation: true))
                    {
                        ODataWriter writer = messageWriter.CreateODataResourceSetWriter(entitySet, entitySet.EntityType());
                        writer.WriteStart(new ODataResourceSet {
                            Id = new Uri("http://www.odata.org/Perf.svc")
                        });
                        for (int i = 0; i < NumberOfEntries; ++i)
                        {
                            writer.WriteStart(entry);
                            writer.WriteEnd();
                        }

                        writer.WriteEnd();
                        writer.Flush();
                    }
                }
            }
        }
        public void WritingSingleComplexProppertyWithNotAllowedTypeWorksWithoutDerivedTypeConstraintButFailedWithDerivedTypeConstraint()
        {
            // Add a <Property Name="Location" Type="NS.Address" />
            var locationProperty = this.edmCustomerType.AddStructuralProperty("Location", new EdmComplexTypeReference(this.edmAddressType, false));

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

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

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

            Assert.Contains("#Customers/$entity\",\"Id\":7,\"Location\":{\"@odata.type\":\"#NS.CnAddress\",\"Street\":\"ShaWay\",", actual);

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

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

            Assert.Equal(Strings.WriterValidationUtils_ValueTypeNotAllowedInDerivedTypeConstraint("NS.CnAddress", "property", "Location"), exception.Message);
        }
        public void WritingResourceWithSameTypeAsEntitySetTypeWithOrWithoutDerivedTypeConstraintWorks()
        {
            ODataResource anotherCustomerResource = new ODataResource
            {
                TypeName   = "NS.Customer",
                Properties = new[] { new ODataProperty {
                                         Name = "Id", Value = 77
                                     } }
            };

            Action <ODataMessageWriter> writeCustomersAction = (messageWriter) =>
            {
                ODataWriter writer = messageWriter.CreateODataResourceSetWriter(this.edmCustomers, this.edmCustomerType); // entityset
                writer.WriteStart(new ODataResourceSet());
                writer.WriteStart(this.odataCustomerResource);
                writer.WriteEnd();
                writer.WriteStart(anotherCustomerResource);
                writer.WriteEnd();
                writer.WriteEnd();
            };

            // EntitySet doesn't have the derived type constraint.
            string customersActual = GetWriterOutput(this.edmModel, writeCustomersAction);

            Assert.Contains("/$metadata#Customers\",\"value\":[{\"Id\":7},{\"Id\":77}]}", customersActual);

            // EntitySet has the derived type constraint.
            SetDerivedTypeAnnotation(this.edmModel, this.edmCustomers, "NS.VipCustomer");
            string customersActualWithDerivedTypeConstraint = GetWriterOutput(this.edmModel, writeCustomersAction);

            Assert.Equal(customersActual, customersActualWithDerivedTypeConstraint);
        }
        public void WritingResourceForEntitySetWithoutDerivedTypeConstraintsWorksButWithConstraintFailed()
        {
            Action <ODataMessageWriter> writeCustomersAction = (messageWriter) =>
            {
                ODataWriter writer = messageWriter.CreateODataResourceSetWriter(this.edmCustomers, this.edmCustomerType); // entityset
                writer.WriteStart(new ODataResourceSet());
                writer.WriteStart(this.odataCustomerResource);
                writer.WriteEnd();
                writer.WriteStart(this.odataNormalResource);
                writer.WriteEnd();
                writer.WriteEnd();
            };

            // EntitySet doesn't have the derived type constraint.
            string normalCustomersActual = GetWriterOutput(this.edmModel, writeCustomersAction);

            Assert.Contains("/$metadata#Customers\",\"value\":[{\"Id\":7},{\"@odata.type\":\"#NS.NormalCustomer\",\"Id\":9,\"Email\":\"[email protected]\"}]}", normalCustomersActual);

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

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

            Assert.Equal(Strings.WriterValidationUtils_ValueTypeNotAllowedInDerivedTypeConstraint("NS.NormalCustomer", "navigation source", "Customers"), exception.Message);
        }
Beispiel #6
0
        private void WriteDynamicTypeEntry(object graph, ODataWriter writer, IEdmTypeReference expectedType,
                                           ODataSerializerContext writeContext)
        {
            var navigationProperties = new Dictionary <IEdmTypeReference, object>();
            var entityType           = expectedType.Definition as EdmEntityType;
            var entry = new ODataEntry()
            {
                TypeName   = expectedType.FullName(),
                Properties = CreateODataPropertiesFromDynamicType(entityType, graph, navigationProperties)
            };

            entry.IsTransient = true;
            writer.WriteStart(entry);
            foreach (IEdmTypeReference type in navigationProperties.Keys)
            {
                var entityContext      = new EntityInstanceContext(writeContext, expectedType.AsEntity(), graph);
                var navigationProperty = entityType.NavigationProperties().FirstOrDefault(p => p.Type.Equals(type));
                var navigationLink     = CreateNavigationLink(navigationProperty, entityContext);
                if (navigationLink != null)
                {
                    writer.WriteStart(navigationLink);
                    WriteDynamicTypeEntry(navigationProperties[type], writer, type, writeContext);
                    writer.WriteEnd();
                }
            }

            writer.WriteEnd();
        }
Beispiel #7
0
        public void WritingResourceWithBaseTypeWhileExpectedTypeIsSubTypeThrows()
        {
            // Arrange
            var model  = GetGraphModel();
            var groups = model.EntityContainer.FindEntitySet("groups");
            var group  = model.SchemaElements.OfType <IEdmEntityType>().FirstOrDefault(c => c.Name == "group");

            ODataResource directoryObject = new ODataResource
            {
                TypeName   = "microsoft.graph.directoryObject",
                Properties = new[] { new ODataProperty {
                                         Name = "id", Value = "abc"
                                     } }
            };

            Action <ODataMessageWriter> writeAction = (messageWriter) =>
            {
                ODataWriter writer = messageWriter.CreateODataResourceSetWriter(groups, group); // entityset
                writer.WriteStart(new ODataResourceSet());
                writer.WriteStart(directoryObject);
                writer.WriteEnd();
                writer.WriteEnd();
            };

            // Act & Assert
            Action test      = () => GetWriterOutput(model, writeAction);
            var    exception = Assert.Throws <ODataException>(test);

            Assert.Equal(Strings.ResourceSetWithoutExpectedTypeValidator_IncompatibleTypes("microsoft.graph.directoryObject", "microsoft.graph.group"), exception.Message);
        }
Beispiel #8
0
        public void WritingResourceWithTypeNotInHeritanceTreeWithResourceSetTypeThrows()
        {
            // Arrange
            var model            = GetGraphModel();
            var directoryObjects = model.EntityContainer.FindEntitySet("directoryObjects");
            var directoryObject  = model.SchemaElements.OfType <IEdmEntityType>().FirstOrDefault(c => c.Name == "directoryObject");

            ODataResource contact = new ODataResource
            {
                TypeName   = "microsoft.graph.contact",
                Properties = new[] { new ODataProperty {
                                         Name = "id", Value = "abc"
                                     }, new ODataProperty {
                                         Name = "displayName", Value = "xyz"
                                     } }                                                                                                           /*open type*/
            };

            Action <ODataMessageWriter> writeAction = (messageWriter) =>
            {
                ODataWriter writer = messageWriter.CreateODataResourceSetWriter(directoryObjects, directoryObject); // entityset
                writer.WriteStart(new ODataResourceSet());
                writer.WriteStart(contact);
                writer.WriteEnd();
                writer.WriteEnd();
            };

            // Act & Assert
            Action test      = () => GetWriterOutput(model, writeAction);
            var    exception = Assert.Throws <ODataException>(test);

            Assert.Equal(Strings.ResourceSetWithoutExpectedTypeValidator_IncompatibleTypes("microsoft.graph.contact", "microsoft.graph.directoryObject"), exception.Message);
        }
Beispiel #9
0
        public void WritingResourceWithTypeInHeritanceTreeWithResourceSetTypeSuccessed()
        {
            // Arrange
            var model            = GetGraphModel();
            var directoryObjects = model.EntityContainer.FindEntitySet("directoryObjects");
            var directoryObject  = model.SchemaElements.OfType <IEdmEntityType>().FirstOrDefault(c => c.Name == "directoryObject");

            ODataResource group = new ODataResource
            {
                TypeName   = "microsoft.graph.group",
                Properties = new[] { new ODataProperty {
                                         Name = "id", Value = "abc"
                                     }, new ODataProperty {
                                         Name = "displayName", Value = "xyz"
                                     } }
            };

            Action <ODataMessageWriter> writeAction = (messageWriter) =>
            {
                ODataWriter writer = messageWriter.CreateODataResourceSetWriter(directoryObjects, directoryObject); // entityset
                writer.WriteStart(new ODataResourceSet());
                writer.WriteStart(group);
                writer.WriteEnd();
                writer.WriteEnd();
            };

            // Act
            string actual = GetWriterOutput(model, writeAction);

            // Assert
            Assert.Equal("{\"@odata.context\":\"http://example.com/$metadata#directoryObjects\",\"value\":[{\"@odata.type\":\"#microsoft.graph.group\",\"id\":\"abc\",\"displayName\":\"xyz\"}]}",
                         actual);
        }
Beispiel #10
0
        public static void WriteResourceSet(IEdmModel model, ODataWriter odataWriter, object value)
        {
            Type valueType = value.GetType();

            IsCollection(valueType, out Type elementType);

            IEdmStructuredType structruedType = model.FindDeclaredType(valueType.FullName) as IEdmStructuredType;

            ODataResourceSet resourceSet = new ODataResourceSet
            {
                TypeName = "Collection(" + elementType.FullName + ")"
            };

            odataWriter.WriteStart(resourceSet);
            IEnumerable items = value as IEnumerable;

            foreach (object item in items)
            {
                if (item == null)
                {
                    odataWriter.WriteStart(resource: null);
                    odataWriter.WriteEnd();
                }
                else
                {
                    WriteResource(model, odataWriter, item);
                }
            }

            odataWriter.WriteEnd();
        }
        private void WriteEntry(ODataWriter odataWriter, int dataSizeKb)
        {
            var entry = new ODataResource
            {
                Id         = new Uri("http://www.odata.org/Perf.svc/Item(1)"),
                EditLink   = new Uri("Item(1)", UriKind.Relative),
                ReadLink   = new Uri("Item(1)", UriKind.Relative),
                TypeName   = "PerformanceServices.Edm.ExchangeAttachment.Item",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "HasAttachments", Value = false
                    },
                }
            };

            var attachmentsP = new ODataNestedResourceInfo()
            {
                Name = "Attachments", IsCollection = true
            };

            var attachmentsResourceSet = new ODataResourceSet()
            {
                TypeName = "Collection(PerformanceServices.Edm.ExchangeAttachment.Attachment)"
            };

            var attachment = dataSizeKb == 0 ? null
                : new ODataResource()
            {
                TypeName   = "PerformanceServices.Edm.ExchangeAttachment.Attachment",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "Name", Value = "attachment"
                    },
                    new ODataProperty {
                        Name = "IsInline", Value = false
                    },
                    new ODataProperty {
                        Name = "LastModifiedTime", Value = new DateTimeOffset(1987, 6, 5, 4, 3, 21, 0, new TimeSpan(0, 0, 3, 0))
                    },
                    new ODataProperty {
                        Name = "Content", Value = new byte[dataSizeKb * 1024]
                    },
                }
            };

            odataWriter.WriteStart(entry);
            odataWriter.WriteStart(attachmentsP);
            odataWriter.WriteStart(attachmentsResourceSet);
            if (attachment != null)
            {
                odataWriter.WriteStart(attachment);
                odataWriter.WriteEnd();
            }
            odataWriter.WriteEnd();
            odataWriter.WriteEnd();
            odataWriter.WriteEnd();
        }
Beispiel #12
0
        private void WriteResourceSet(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer,
                                      ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(resourceSetType != null);

            IEdmStructuredTypeReference elementType = GetResourceType(resourceSetType);

            ODataEdmTypeSerializer resourceSerializer = SerializerProvider.GetEdmTypeSerializer(elementType);

            if (resourceSerializer == null)
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName()));
            }

            ODataResourceSet resourceSet = GetResourceSet(enumerable, resourceSetType, elementType, writeContext);

            // create the nextLinkGenerator for the current resourceSet and then set the nextpagelink to null to support JSON odata.streaming.
            Func <object, Uri> nextLinkGenerator = GetNextLinkGenerator(resourceSet, enumerable, writeContext);

            resourceSet.NextPageLink = null;

            writer.WriteStart(resourceSet);
            object lastResource = null;

            foreach (object item in enumerable)
            {
                lastResource = item;
                if (item == null || item is NullEdmComplexObject)
                {
                    if (elementType.IsEntity())
                    {
                        throw new SerializationException(SRResources.NullElementInCollection);
                    }

                    // for null complex element, it can be serialized as "null" in the collection.
                    writer.WriteStart(resource: null);
                    writer.WriteEnd();
                }
                else
                {
                    resourceSerializer.WriteObjectInline(item, elementType, writer, writeContext);
                }
            }

            // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(resourceSet),
            // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
            // the next page link is not set when calling WriteStart(resourceSet) but is instead set later on that resourceSet
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.
            resourceSet.NextPageLink = nextLinkGenerator(lastResource);

            writer.WriteEnd();
        }
Beispiel #13
0
            private async Task SerializeBuffered(OeEntryFactory entryFactory, Db.OeEntityAsyncEnumerator asyncEnumerator, Stream stream)
            {
                var values = new List <Object>();

                while (await asyncEnumerator.MoveNextAsync().ConfigureAwait(false))
                {
                    values.Add(asyncEnumerator.Current);
                }

                var resourceSet = new ODataResourceSet();

                resourceSet.Count = values.Count;
                Writer.WriteStart(resourceSet);

                foreach (Object value in values)
                {
                    int?          dummy;
                    ODataResource entry = CreateEntry(entryFactory, entryFactory.GetValue(value, out dummy));
                    Writer.WriteStart(entry);
                    foreach (OeEntryFactory navigationLink in entryFactory.NavigationLinks)
                    {
                        WriteNavigationLink(value, navigationLink);
                    }
                    Writer.WriteEnd();
                }

                Writer.WriteEnd();
            }
Beispiel #14
0
        public static void WriteODataFeed(IEdmModel model, Stream stream)
        {
            // Create a ODataEntry
            var entry = new ODataEntry()
            {
                Properties = new List <ODataProperty>()
                {
                    new ODataProperty
                    {
                        Name = "ProductId", Value = 100
                    },
                    new ODataProperty
                    {
                        Name = "Name", Value = "The World"
                    },
                    new ODataProperty
                    {
                        Name = "SkinColor", Value = new ODataEnumValue("Green", DefaultNamespace + ".Color")
                    },
                    new ODataProperty
                    {
                        Name = "UserAccess", Value = new ODataEnumValue("ReadWrite, Execute", DefaultNamespace + ".AccessLevel")
                    }
                }
            };

            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings();

            writerSettings.ODataUri = new ODataUri()
            {
                ServiceRoot = ServiceRootUri
            };
            writerSettings.PayloadBaseUri = ServiceRootUri;
            writerSettings.SetContentType("application/json;odata.metadata=full", Encoding.UTF8.WebName);
            writerSettings.AutoComputePayloadMetadataInJson = true;

            var responseMessage = new ODataResponseMessage(stream);

            using (var messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
            {
                IEdmEntitySet entitySet  = model.FindDeclaredEntitySet("Products");
                ODataWriter   feedWriter = messageWriter.CreateODataFeedWriter(entitySet);

                var feed = new ODataFeed {
                    Id = new Uri(ServiceRootUri, "Products")
                };
                feedWriter.WriteStart(feed);
                feedWriter.WriteStart(entry);
                feedWriter.WriteEnd();
                feedWriter.WriteEnd();
                feedWriter.Flush();
            }
        }
        private void WriteNavigationLinks(EntityInstanceContext context, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            foreach (IEdmNavigationProperty navProperty in _edmEntityTypeReference.NavigationProperties())
            {
                IEdmTypeReference propertyType  = navProperty.Type;
                object            propertyValue = context.EntityInstance.GetType().GetProperty(navProperty.Name).GetValue(context.EntityInstance, index: null);

                if (writeContext.EntitySet != null)
                {
                    IEdmEntitySet         currentEntitySet = writeContext.EntitySet.FindNavigationTarget(navProperty);
                    IEntitySetLinkBuilder linkBuilder      = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);

                    ODataNavigationLink navigationLink = new ODataNavigationLink
                    {
                        IsCollection = propertyType.IsCollection(),
                        Name         = navProperty.Name,
                        Url          = linkBuilder.BuildNavigationLink(context, navProperty)
                    };

                    ODataQueryProjectionNode expandNode = null;
                    if (writeContext.CurrentProjectionNode != null)
                    {
                        expandNode = writeContext.CurrentProjectionNode.Expands.FirstOrDefault(p => p.Name == navProperty.Name);
                    }

                    if (expandNode != null && propertyValue != null)
                    {
                        writer.WriteStart(navigationLink);
                        ODataSerializer serializer = SerializerProvider.GetEdmTypeSerializer(propertyType);
                        if (serializer == null)
                        {
                            throw Error.NotSupported(SRResources.TypeCannotBeSerialized, navProperty.Type.FullName(), typeof(ODataMediaTypeFormatter).Name);
                        }

                        ODataSerializerWriteContext childWriteContext = new ODataSerializerWriteContext(writeContext.ResponseContext);
                        childWriteContext.UrlHelper             = writeContext.UrlHelper;
                        childWriteContext.EntitySet             = currentEntitySet;
                        childWriteContext.RootProjectionNode    = writeContext.RootProjectionNode;
                        childWriteContext.CurrentProjectionNode = expandNode;

                        serializer.WriteObjectInline(propertyValue, writer, childWriteContext);
                        writer.WriteEnd();
                    }
                    else if (!writeContext.IsRequest)
                    {
                        // delayed links cannot be written on requests
                        writer.WriteStart(navigationLink);
                        writer.WriteEnd();
                    }
                }
            }
        }
Beispiel #16
0
        private void WriteNavigationProperty(ODataWriter writer, Object value, PropertyInfo navigationProperty)
        {
            Object navigationValue = navigationProperty.GetValue(value);

            if (!_stack.Add(navigationValue))
            {
                return;
            }

            bool isCollection = OeExpressionHelper.GetCollectionItemType(navigationProperty.PropertyType) != null;
            var  resourceInfo = new ODataNestedResourceInfo()
            {
                IsCollection = isCollection,
                Name         = navigationProperty.Name
            };

            writer.WriteStart(resourceInfo);

            if (navigationValue == null)
            {
                if (isCollection)
                {
                    writer.WriteStart(new ODataResourceSet());
                }
                else
                {
                    writer.WriteStart((ODataResource)null);
                }
                writer.WriteEnd();
            }
            else
            {
                var entityPropertiesInfo = default(EntityPropertiesInfo);
                if (isCollection)
                {
                    writer.WriteStart(new ODataResourceSet());
                    foreach (Object entity in (IEnumerable)navigationValue)
                    {
                        WriteEntry(writer, entity, ref entityPropertiesInfo);
                    }
                    writer.WriteEnd();
                }
                else
                {
                    WriteEntry(writer, navigationValue, ref entityPropertiesInfo);
                }
            }

            writer.WriteEnd();
            _stack.Remove(navigationValue);
        }
Beispiel #17
0
            public async Task SerializeAsync(OeEntryFactory entryFactory, Db.OeAsyncEnumerator asyncEnumerator, OeQueryContext queryContext)
            {
                var resourceSet = new ODataResourceSet()
                {
                    Count = asyncEnumerator.Count
                };

                _writer.WriteStart(resourceSet);

                Object buffer       = null;
                int    count        = 0;
                var    dbEnumerator = entryFactory.IsTuple ?
                                      (Db.IOeDbEnumerator) new Db.OeDbEnumerator(asyncEnumerator, entryFactory) : new Db.OeEntityDbEnumerator(asyncEnumerator, entryFactory);

                while (await dbEnumerator.MoveNextAsync().ConfigureAwait(false))
                {
                    Object value = dbEnumerator.Current;
                    await WriteEntry(dbEnumerator, value, _queryContext.NavigationNextLink).ConfigureAwait(false);

                    count++;
                    buffer = dbEnumerator.ClearBuffer();
                }

                if (queryContext.PageSize > 0 && count > 0 && (asyncEnumerator.Count ?? Int32.MaxValue) > count)
                {
                    resourceSet.NextPageLink = BuildNextPageLink(queryContext, buffer);
                }

                _writer.WriteEnd();
            }
Beispiel #18
0
        /// <summary>
        /// Writes a ReferenceLinks
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the ReferenceLinks.</param>
        public static void WriteReferenceLinks(ODataWriter writer, IEnumerable element, IEdmNavigationSource entitySource, ODataVersion targetVersion, ODataNavigationLink navigationLink)
        {
            IEnumerable <ODataEntry> links = ODataObjectModelConverter.ConvertToODataEntityReferenceLinks(element, entitySource, targetVersion);
            var feed = new ODataFeed {
            };

            writer.WriteStart(feed);
            foreach (var entry in links)
            {
                entry.InstanceAnnotations.Add(new ODataInstanceAnnotation("Link.AnnotationByFeed", new ODataPrimitiveValue(true)));
                writer.WriteStart(entry);
                writer.WriteEnd();
            }
            writer.WriteEnd();
        }
    /// <summary>
    /// Serializes the open complex type as an <see cref="ODataUntypedValue"/>.
    /// </summary>
    /// <param name="graph"></param>
    /// <param name="expectedType"></param>
    /// <param name="writer"></param>
    /// <param name="writeContext"></param>
    public override void WriteObjectInline(
        object graph,
        IEdmTypeReference expectedType,
        ODataWriter writer,
        ODataSerializerContext writeContext)
    {
        // This cast is safe because the type is checked before using this serializer.
        var mongoData  = (MongoData)graph;
        var properties = new List <ODataProperty>();

        foreach (var item in mongoData.Document)
        {
            properties.Add(new ODataProperty
            {
                Name  = item.Key,
                Value = new ODataUntypedValue
                {
                    RawValue = JsonConvert.SerializeObject(item.Value),
                },
            });
        }
        writer.WriteStart(new ODataResource
        {
            TypeName   = expectedType.FullName(),
            Properties = properties,
        });
        writer.WriteEnd();
    }
Beispiel #20
0
        private async Task SerializeAsync(ODataWriter writer)
        {
            var resourceSet = new ODataResourceSet()
            {
                Count = Count
            };

            writer.WriteStart(resourceSet);

            int count  = 0;
            T   entity = default;
            EntityPropertiesInfo entityPropertiesInfo = default;

            while (await _entities.MoveNext())
            {
                entity = _entities.Current;
                _stack.Add(entity);
                WriteEntry(writer, entity, ref entityPropertiesInfo);
                _stack.Remove(entity);
                count++;
            }

            if (PageSize > 0 && count > 0 && (Count ?? Int32.MaxValue) > count)
            {
                resourceSet.NextPageLink = BuildNextPageLink(OeSkipTokenParser.GetSkipToken(_edmModel, GetKeys(entity)));
            }

            writer.WriteEnd();
        }
        public void WritingEdmPrimitiveProppertyWithNotAllowedTypeWorksWithoutDerivedTypeConstraintButFailedWithDerivedTypeConstraint()
        {
            // Add a <Property Name="Data" Type="Edm.PrimitiveType" />
            var locationProperty = this.edmCustomerType.AddStructuralProperty("Data", EdmCoreModel.Instance.GetPrimitiveType(false));

            ODataResource customer = new ODataResource
            {
                TypeName   = "NS.Customer",
                Properties = new[] { new ODataProperty {
                                         Name = "Id", Value = 7
                                     }, new ODataProperty {
                                         Name = "Data", Value = 8.9
                                     } }
            };

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

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

            Assert.Contains("#Customers/$entity\",\"Id\":7,\"[email protected]\":\"#Double\",\"Data\":8.9}", actual);

            // Negative test case --EdmPrimitive property has the derived type constraint.
            SetDerivedTypeAnnotation(this.edmModel, locationProperty, "Edm.Boolean", "Edm.Int32");

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

            Assert.Equal(Strings.WriterValidationUtils_ValueTypeNotAllowedInDerivedTypeConstraint("Edm.Double", "property", "Data"), exception.Message);
        }
Beispiel #22
0
        private void WriteEntity(Stream stream, OeEntityItem entityItem)
        {
            var settings = new ODataMessageWriterSettings()
            {
                BaseUri  = _baseUri,
                Version  = ODataVersion.V4,
                ODataUri = new ODataUri()
                {
                    ServiceRoot = _baseUri
                },
                EnableMessageStreamDisposal = false
            };

            IODataResponseMessage responseMessage = new OeInMemoryMessage(stream, null);

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, settings, _model))
            {
                ODataUtils.SetHeadersForPayload(messageWriter, ODataPayloadKind.Resource);
                ODataWriter writer = messageWriter.CreateODataResourceWriter(entityItem.EntitySet, entityItem.EntityType);

                entityItem.RefreshEntry();
                writer.WriteStart(entityItem.Entry);
                writer.WriteEnd();
            }
        }
Beispiel #23
0
        /// <summary>
        /// Writes an OData entry.
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the entry.</param>
        /// <param name="element">The item from the data store to write.</param>
        /// <param name="navigationSource">The navigation source in the model that the entry belongs to.</param>
        /// <param name="model">The data store model.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <param name="selectExpandClause">The SelectExpandClause.</param>
        public static void WriteEntry(ODataWriter writer, object element, IEdmNavigationSource entitySource, ODataVersion targetVersion, SelectExpandClause selectExpandClause, Dictionary <string, string> incomingHeaders = null)
        {
            var entry = ODataObjectModelConverter.ConvertToODataEntry(element, entitySource, targetVersion);

            entry.ETag = Utility.GetETagValue(element);

            if (selectExpandClause != null && selectExpandClause.SelectedItems.OfType <PathSelectItem>().Any())
            {
                ExpandSelectItemHandler selectItemHandler = new ExpandSelectItemHandler(entry);
                foreach (var item in selectExpandClause.SelectedItems.OfType <PathSelectItem>())
                {
                    item.HandleWith(selectItemHandler);
                }

                entry = selectItemHandler.ProjectedEntry;
            }

            CustomizeEntry(incomingHeaders, entry);

            writer.WriteStart(entry);

            // gets all of the expandedItems, including ExpandedRefernceSelectItem and ExpandedNavigationItem
            var expandedItems = selectExpandClause == null ? null : selectExpandClause.SelectedItems.OfType <ExpandedReferenceSelectItem>();

            WriteNavigationLinks(writer, element, entry.ReadLink, entitySource, targetVersion, expandedItems);
            writer.WriteEnd();
        }
        private string WriteAndVerifyCarEntry(StreamResponseMessage responseMessage, ODataWriter odataWriter,
                                              bool hasModel, string mimeType)
        {
            var carEntry = WritePayloadHelper.CreateCarEntry(hasModel);

            odataWriter.WriteStart(carEntry);

            // Finish writing the entry.
            odataWriter.WriteEnd();

            // Some very basic verification for the payload.
            bool verifyEntryCalled          = false;
            Action <ODataEntry> verifyEntry = (entry) =>
            {
                Assert.AreEqual(4, entry.Properties.Count(), "entry.Properties.Count");
                Assert.IsNotNull(entry.MediaResource, "entry.MediaResource");
                Assert.IsTrue(entry.EditLink.AbsoluteUri.Contains("Car(11)"), "entry.EditLink");
                Assert.IsTrue(entry.ReadLink == null || entry.ReadLink.AbsoluteUri.Contains("Car(11)"), "entry.ReadLink");
                Assert.AreEqual(1, entry.InstanceAnnotations.Count, "entry.InstanceAnnotations.Count");

                verifyEntryCalled = true;
            };

            Stream stream = responseMessage.GetStream();

            if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
            {
                stream.Seek(0, SeekOrigin.Begin);
                WritePayloadHelper.ReadAndVerifyFeedEntryMessage(false, responseMessage, WritePayloadHelper.CarSet, WritePayloadHelper.CarType, null, verifyEntry,
                                                                 null);
                Assert.IsTrue(verifyEntryCalled, "Verification action not called.");
            }

            return(WritePayloadHelper.ReadStreamContent(stream));
        }
    public override void WriteObjectInline(
        object graph,
        IEdmTypeReference expectedType,
        ODataWriter writer,
        ODataSerializerContext writeContext)
    {
        // This cast is safe because the type is checked before using this serializer.
        var dictionary = (IDictionary <string, object>)graph;
        var properties = new List <ODataProperty>();

        foreach (var(key, value) in dictionary)
        {
            properties.Add(new ODataProperty
            {
                Name  = key,
                Value = new ODataUntypedValue
                {
                    RawValue = JsonConvert.SerializeObject(value),
                },
            });
        }
        writer.WriteStart(new ODataResource
        {
            TypeName   = "Edm.Untyped",
            Properties = properties,
        });
        writer.WriteEnd();
    }
Beispiel #26
0
        private async Task SerializeAsync(ODataWriter writer, OeMetadataLevel metadataLevel)
        {
            ClrPropertiesInfo clrPropertiesInfo = GetClrPropertiesInfo(_edmModel, _odataUri.SelectAndExpand, metadataLevel, typeof(T), null);

            var resourceSet = new ODataResourceSet()
            {
                Count = Count
            };

            writer.WriteStart(resourceSet);

            int count  = 0;
            T   entity = default;

            while (await _entities.MoveNext())
            {
                entity = _entities.Current;
                _stack.Add(entity);
                WriteEntry(writer, entity, clrPropertiesInfo);
                _stack.Remove(entity);
                count++;
            }

            if (PageSize > 0 && count > 0 && (Count ?? Int32.MaxValue) > count)
            {
                resourceSet.NextPageLink = BuildNextPageLink(OeSkipTokenParser.GetSkipToken(_edmModel, GetKeys(entity)));
            }

            writer.WriteEnd();
        }
Beispiel #27
0
        private string GetWriterOutputForContentTypeAndKnobValue(ODataEntry entry, EdmModel model, IEdmEntitySetBase entitySet, EdmEntityType entityType)
        {
            MemoryStream          outputStream = new MemoryStream();
            IODataResponseMessage message      = new InMemoryMessage()
            {
                Stream = outputStream
            };

            message.SetHeader("Content-Type", "application/json;odata.metadata=full");
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings()
            {
                AutoComputePayloadMetadataInJson = true,
            };

            settings.SetServiceDocumentUri(new Uri("http://example.com"));

            string output;

            using (var messageWriter = new ODataMessageWriter(message, settings, model))
            {
                ODataWriter writer = messageWriter.CreateODataEntryWriter(entitySet, entityType);
                writer.WriteStart(entry);
                writer.WriteEnd();
                outputStream.Seek(0, SeekOrigin.Begin);
                output = new StreamReader(outputStream).ReadToEnd();
            }

            return(output);
        }
Beispiel #28
0
        internal void WriteNavigationLink(EntityDescriptor entityDescriptor, IEnumerable <LinkDescriptor> relatedLinks, ODataWriter odataWriter)
        {
            ClientTypeAnnotation clientTypeAnnotation = null;

            foreach (LinkDescriptor descriptor in relatedLinks)
            {
                descriptor.ContentGeneratedForSave = true;
                if (clientTypeAnnotation == null)
                {
                    ClientEdmModel model = ClientEdmModel.GetModel(this.requestInfo.MaxProtocolVersion);
                    clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType()));
                }
                ODataNavigationLink navigationLink = new ODataNavigationLink {
                    Url          = this.requestInfo.EntityTracker.GetEntityDescriptor(descriptor.Target).GetLatestEditLink(),
                    IsCollection = new bool?(clientTypeAnnotation.GetProperty(descriptor.SourceProperty, false).IsEntityCollection),
                    Name         = descriptor.SourceProperty
                };
                odataWriter.WriteStart(navigationLink);
                ODataEntityReferenceLink entityReferenceLink = new ODataEntityReferenceLink {
                    Url = navigationLink.Url
                };
                odataWriter.WriteEntityReferenceLink(entityReferenceLink);
                odataWriter.WriteEnd();
            }
        }
Beispiel #29
0
        private void WriteNavigationLink(ODataWriter writer, ODataNestedResourceInfo link)
        {
            writer.WriteStart(link);
            var expanded = link.GetAnnotation <ODataNavigationLinkExpandedItemObjectModelAnnotation>();

            if (expanded != null)
            {
                var feed = expanded.ExpandedItem as ODataResourceSet;
                if (feed != null)
                {
                    this.WriteFeed(writer, feed);
                }
                else
                {
                    ODataResource entry = expanded.ExpandedItem as ODataResource;
                    if (entry != null || expanded.ExpandedItem == null)
                    {
                        this.WriteEntry(writer, entry);
                    }
                    else
                    {
                        ExceptionUtilities.Assert(expanded.ExpandedItem is ODataEntityReferenceLink, "Content of a nav. link can only be a feed, entry or entity reference link.");
                        writer.WriteEntityReferenceLink((ODataEntityReferenceLink)expanded.ExpandedItem);
                    }
                }
            }

            writer.WriteEnd();
        }
Beispiel #30
0
        /// <summary>
        /// Writes the given deltaDeletedEntry specified by the parameter graph as a part of an existing OData message using the given
        /// messageWriter and the writeContext.
        /// </summary>
        /// <param name="graph">The object to be written.</param>
        /// <param name="writer">The <see cref="ODataDeltaWriter" /> to be used for writing.</param>
        /// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
        public virtual void WriteDeltaDeletedEntry(object graph, ODataWriter writer, ODataSerializerContext writeContext)
        {
            EdmDeltaDeletedEntityObject edmDeltaDeletedEntity = graph as EdmDeltaDeletedEntityObject;

            if (edmDeltaDeletedEntity == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
            }

            Uri id = StringToUri(edmDeltaDeletedEntity.Id);
            ODataDeletedResource deletedResource = new ODataDeletedResource(id, edmDeltaDeletedEntity.Reason);

            if (edmDeltaDeletedEntity.NavigationSource != null)
            {
                ODataResourceSerializationInfo serializationInfo = new ODataResourceSerializationInfo
                {
                    NavigationSourceName = edmDeltaDeletedEntity.NavigationSource.Name
                };
                deletedResource.SetSerializationInfo(serializationInfo);
            }

            if (deletedResource != null)
            {
                writer.WriteStart(deletedResource);
                writer.WriteEnd();
            }
        }
        private void WriteEntry(ODataWriter writer, ODataItem[] itemsToWrite, ref int currentIdx)
        {
            if (currentIdx < itemsToWrite.Length)
            {
                ODataEntry entry = (ODataEntry)itemsToWrite[currentIdx++];
                writer.WriteStart(entry);
                while (currentIdx < itemsToWrite.Length)
                {
                    if (itemsToWrite[currentIdx] is ODataNavigationLink)
                    {
                        this.WriteLink(writer, itemsToWrite, ref currentIdx);
                    }
                    else if (itemsToWrite[currentIdx] is ODataNavigationLinkEnd)
                    {
                        currentIdx++;
                        writer.WriteEnd();
                        return;
                    }
                    else
                    {
                        break;
                    }
                }

                writer.WriteEnd();
            }
        }
        private void WriteLink(ODataWriter writer, ODataItem[] itemsToWrite, ref int currentIdx)
        {
            if (currentIdx < itemsToWrite.Length)
            {
                ODataNavigationLink link = (ODataNavigationLink)itemsToWrite[currentIdx++];
                writer.WriteStart(link);
                if (currentIdx < itemsToWrite.Length)
                {
                    if (itemsToWrite[currentIdx] is ODataEntry)
                    {
                        this.WriteEntry(writer, itemsToWrite, ref currentIdx);
                    }
                    else if (itemsToWrite[currentIdx] is ODataFeed)
                    {
                        this.WriteFeed(writer, itemsToWrite, ref currentIdx);
                    }
                }

                writer.WriteEnd();
            }
        }
        private void WriteFeed(ODataWriter writer, ODataItem[] itemsToWrite, ref int currentIdx)
        {
            if (currentIdx < itemsToWrite.Length)
            {
                ODataFeed feed = (ODataFeed)itemsToWrite[currentIdx++];
                writer.WriteStart(feed);
                while (currentIdx < itemsToWrite.Length && itemsToWrite[currentIdx] is ODataEntry)
                {
                    this.WriteEntry(writer, itemsToWrite, ref currentIdx);
                }

                writer.WriteEnd();
            }
        }