public void CanConfigureAllLinksViaIdLink()
        {
            // Arrange
            ODataModelBuilder builder = GetCommonModel();
            var expectedEditLink = "http://server/service/Products(15)";

            var products = builder.EntitySet<EntitySetLinkConfigurationTest_Product>("Products");
            products.HasIdLink(c =>
                string.Format(
                    "http://server/service/Products({0})",
                    c.GetPropertyValue("ID")
                ),
                followsConventions: false);

            var actor = builder.EntitySets.Single();
            var model = builder.GetEdmModel();
            var productType = model.SchemaElements.OfType<IEdmEntityType>().Single();
            var productsSet = model.SchemaElements.OfType<IEdmEntityContainer>().Single().EntitySets().Single();
            var productInstance = new EntitySetLinkConfigurationTest_Product { ID = 15 };
            var serializerContext = new ODataSerializerContext { Model = model, NavigationSource = productsSet };
            var entityContext = new EntityInstanceContext(serializerContext, productType.AsReference(), productInstance);
            var linkBuilderAnnotation = new NavigationSourceLinkBuilderAnnotation(actor);

            // Act
            var selfLinks = linkBuilderAnnotation.BuildEntitySelfLinks(entityContext, ODataMetadataLevel.Default);

            // Assert
            Assert.NotNull(selfLinks.EditLink);
            Assert.Equal(expectedEditLink, selfLinks.EditLink.ToString());
            Assert.NotNull(selfLinks.ReadLink);
            Assert.Equal(expectedEditLink, selfLinks.ReadLink.ToString());
            Assert.NotNull(selfLinks.IdLink);
            Assert.Equal(expectedEditLink, selfLinks.IdLink);
        }
        public void WriteObject_WritesValueReturnedFrom_CreateODataCollectionValue()
        {
            // Arrange
            MemoryStream stream = new MemoryStream();
            IODataResponseMessage message = new ODataMessageWrapper(stream);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings()
            {
                ODataUri = new ODataUri { ServiceRoot = new Uri("http://any/") }
            };

            settings.SetContentType(ODataFormat.Json);

            ODataMessageWriter messageWriter = new ODataMessageWriter(message, settings);
            Mock<ODataCollectionSerializer> serializer = new Mock<ODataCollectionSerializer>(new DefaultODataSerializerProvider());
            ODataSerializerContext writeContext = new ODataSerializerContext { RootElementName = "CollectionName", Model = _model };
            IEnumerable enumerable = new object[0];
            ODataCollectionValue collectionValue = new ODataCollectionValue { TypeName = "NS.Name", Items = new[] { 0, 1, 2 } };

            serializer.CallBase = true;
            serializer
                .Setup(s => s.CreateODataCollectionValue(enumerable, It.Is<IEdmTypeReference>(e => e.Definition == _edmIntType.Definition), writeContext))
                .Returns(collectionValue).Verifiable();

            // Act
            serializer.Object.WriteObject(enumerable, typeof(int[]), messageWriter, writeContext);

            // Assert
            serializer.Verify();
            stream.Seek(0, SeekOrigin.Begin);
            string result = new StreamReader(stream).ReadToEnd();
            Assert.Equal("{\"@odata.context\":\"http://any/$metadata#Collection(Edm.Int32)\",\"value\":[0,1,2]}", result);
        }
        /// <inheridoc />
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            if (graph != null)
            {
                ODataEntityReferenceLinks entityReferenceLinks = graph as ODataEntityReferenceLinks;
                if (entityReferenceLinks == null)
                {
                    IEnumerable<Uri> uris = graph as IEnumerable<Uri>;
                    if (uris == null)
                    {
                        throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
                    }

                    entityReferenceLinks = new ODataEntityReferenceLinks
                    {
                        Links = uris.Select(uri => new ODataEntityReferenceLink { Url = uri })
                    };
                }

                messageWriter.WriteEntityReferenceLinks(entityReferenceLinks);
            }
        }
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw new ArgumentNullException("messageWriter");
            }
            if (writeContext == null)
            {
                throw new ArgumentNullException("writeContext");
            }

            if (graph != null)
            {
                Uri[] uris = graph as Uri[];
                if (uris == null)
                {
                    throw new SerializationException("Cannot write the type");
                }

                messageWriter.WriteEntityReferenceLinks(new ODataEntityReferenceLinks
                {
                    Links = uris.Select(uri => new ODataEntityReferenceLink { Url = uri })
                });
            }
        }
        public ODataDeltaFeedSerializerTests()
        {
            _model = SerializationTestsHelpers.SimpleCustomerOrderModel();
            _customerSet = _model.EntityContainer.FindEntitySet("Customers");
            _model.SetAnnotationValue(_customerSet.EntityType(), new ClrTypeAnnotation(typeof(Customer)));
            _path = new ODataPath(new EntitySetPathSegment(_customerSet));
            _customers = new[] {
                new Customer()
                {
                    FirstName = "Foo",
                    LastName = "Bar",
                    ID = 10,
                },
                new Customer()
                {
                    FirstName = "Foo",
                    LastName = "Bar",
                    ID = 42,
                }
            };

            _deltaFeedCustomers = new EdmChangedObjectCollection(_customerSet.EntityType());
            EdmDeltaEntityObject newCustomer = new EdmDeltaEntityObject(_customerSet.EntityType());
            newCustomer.TrySetPropertyValue("ID", 10);
            newCustomer.TrySetPropertyValue("FirstName", "Foo");
            _deltaFeedCustomers.Add(newCustomer);

             _customersType = _model.GetEdmTypeReference(typeof(Customer[])).AsCollection();

            _writeContext = new ODataSerializerContext() { NavigationSource = _customerSet, Model = _model, Path = _path };
        }
        public void ODataEntityReferenceLinkSerializer_Serializes_UrisAndEntityReferenceLinks(object uris)
        {
            // Arrange
            ODataEntityReferenceLinksSerializer serializer = new ODataEntityReferenceLinksSerializer();
            ODataSerializerContext writeContext = new ODataSerializerContext();
            MemoryStream stream = new MemoryStream();
            IODataResponseMessage message = new ODataMessageWrapper(stream);

            ODataMessageWriterSettings settings = new ODataMessageWriterSettings
            {
                ODataUri = new ODataUri { ServiceRoot = new Uri("http://any/") }
            };

            settings.SetContentType(ODataFormat.Json);
            ODataMessageWriter writer = new ODataMessageWriter(message, settings);

            // Act
            serializer.WriteObject(uris, typeof(ODataEntityReferenceLinks), writer, writeContext);
            stream.Seek(0, SeekOrigin.Begin);
            string result = new StreamReader(stream).ReadToEnd();

            // Assert
            Assert.Equal("{\"@odata.context\":\"http://any/$metadata#Collection($ref)\"," +
                "\"value\":[{\"@odata.id\":\"http://uri1/\"},{\"@odata.id\":\"http://uri2/\"}]}",
                result);
        }
示例#7
0
        /// <summary>
        /// Writes the entity result to the response message.
        /// </summary>
        /// <param name="graph">The entity result to write.</param>
        /// <param name="type">The type of the entity.</param>
        /// <param name="messageWriter">The message writer.</param>
        /// <param name="writeContext">The writing context.</param>
        public override void WriteObject(
            object graph,
            Type type,
            ODataMessageWriter messageWriter,
            ODataSerializerContext writeContext)
        {
            RawResult rawResult = graph as RawResult;
            if (rawResult != null)
            {
                graph = rawResult.Result;
                type = rawResult.Type;
            }

            if (writeContext != null)
            {
                graph = RestierPrimitiveSerializer.ConvertToPayloadValue(graph, writeContext);
            }

            if (graph == null)
            {
                // This is to make ODataRawValueSerializer happily serialize null value.
                graph = string.Empty;
            }

            base.WriteObject(graph, type, messageWriter, writeContext);
        }
        public void Singleton_CanOnlyConfigureIdLinkViaIdLinkFactory()
        {
            // Arrange
            ODataModelBuilder builder = GetSingletonModel();
            const string ExpectedEditLink = "http://server/service/Exchange";

            var product = builder.Singleton<SingletonProduct>("Exchange");
            product.HasIdLink(c => new Uri("http://server/service/Exchange"),
                followsConventions: false);

            var exchange = builder.Singletons.Single();
            var model = builder.GetEdmModel();
            var productType = model.SchemaElements.OfType<IEdmEntityType>().Single();
            var singleton = model.SchemaElements.OfType<IEdmEntityContainer>().Single().FindSingleton("Exchange");
            var singletonInstance = new SingletonProduct { ID = 15 };
            var serializerContext = new ODataSerializerContext { Model = model, NavigationSource = singleton };
            var entityContext = new EntityInstanceContext(serializerContext, productType.AsReference(), singletonInstance);
            var linkBuilderAnnotation = new NavigationSourceLinkBuilderAnnotation(exchange);

            // Act
            var selfLinks = linkBuilderAnnotation.BuildEntitySelfLinks(entityContext, ODataMetadataLevel.FullMetadata);

            // Assert
            Assert.NotNull(selfLinks.IdLink);
            Assert.Equal(ExpectedEditLink, selfLinks.IdLink.ToString());
            Assert.Null(selfLinks.ReadLink);
            Assert.Null(selfLinks.EditLink);
        }
        public void CanSerializerSingleton()
        {
            // Arrange
            const string expect = "{" +
                "\"@odata.context\":\"http://localhost/odata/$metadata#Boss\"," +
                "\"@odata.id\":\"http://localhost/odata/Boss\"," +
                "\"@odata.editLink\":\"http://localhost/odata/Boss\"," +
                "\"EmployeeId\":987,\"EmployeeName\":\"John Mountain\"}";

            IEdmModel model = GetEdmModel();
            IEdmSingleton singleton = model.EntityContainer.FindSingleton("Boss");
            HttpRequestMessage request = GetRequest(model, singleton);
            ODataSerializerContext readContext = new ODataSerializerContext()
            {
                Url = new UrlHelper(request),
                Path = request.ODataProperties().Path,
                Model = model,
                NavigationSource = singleton
            };

            ODataSerializerProvider serializerProvider = new DefaultODataSerializerProvider();
            EmployeeModel boss = new EmployeeModel {EmployeeId = 987, EmployeeName = "John Mountain"};
            MemoryStream bufferedStream = new MemoryStream();

            // Act
            ODataEntityTypeSerializer serializer = new ODataEntityTypeSerializer(serializerProvider);
            serializer.WriteObject(boss, typeof(EmployeeModel), GetODataMessageWriter(model, bufferedStream), readContext);

            // Assert
            string result = Encoding.UTF8.GetString(bufferedStream.ToArray());
            Assert.Equal(expect, result);
        }
        /// <inheritdoc/>
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (graph == null)
            {
                throw Error.ArgumentNull("graph");
            }
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            ODataError oDataError = graph as ODataError;
            if (oDataError == null)
            {
                HttpError httpError = graph as HttpError;
                if (httpError == null)
                {
                    string message = Error.Format(SRResources.ErrorTypeMustBeODataErrorOrHttpError, graph.GetType().FullName);
                    throw new SerializationException(message);
                }
                else
                {
                    oDataError = httpError.CreateODataError();
                }
            }

            bool includeDebugInformation = oDataError.InnerError != null;
            messageWriter.WriteError(oDataError, includeDebugInformation);
        }
        public void WriteObject_Calls_CreateODataComplexValue()
        {
            // Arrange
            MemoryStream stream = new MemoryStream();
            IODataResponseMessage message = new ODataMessageWrapper(stream);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings();
            settings.SetServiceDocumentUri(new Uri("http://any/"));
            settings.SetContentType(ODataFormat.Atom);
            ODataMessageWriter messageWriter = new ODataMessageWriter(message, settings);
            Mock<ODataComplexTypeSerializer> serializer = new Mock<ODataComplexTypeSerializer>(new DefaultODataSerializerProvider());
            ODataSerializerContext writeContext = new ODataSerializerContext { RootElementName = "ComplexPropertyName", Model = _model };
            object graph = new object();
            ODataComplexValue complexValue = new ODataComplexValue
            {
                TypeName = "NS.Name",
                Properties = new[] { new ODataProperty { Name = "Property1", Value = 42 } }
            };

            serializer.CallBase = true;
            serializer.Setup(s => s.CreateODataComplexValue(graph, It.Is<IEdmComplexTypeReference>(e => e.Definition == _addressType), writeContext))
                .Returns(complexValue).Verifiable();

            // Act
            serializer.Object.WriteObject(graph, typeof(Address), messageWriter, writeContext);

            // Assert
            serializer.Verify();
            stream.Seek(0, SeekOrigin.Begin);
            XElement element = XElement.Load(stream);
            Assert.Equal("value", element.Name.LocalName);
            Assert.Equal("#NS.Name", element.Attributes().Single(a => a.Name.LocalName == "type").Value);
            Assert.Equal(1, element.Descendants().Count());
            Assert.Equal("42", element.Descendants().Single().Value);
            Assert.Equal("Property1", element.Descendants().Single().Name.LocalName);
        }
示例#12
0
        /// <summary>
        /// Creates an <see cref="ODataEnumValue"/> for the object represented by <paramref name="graph"/>.
        /// </summary>
        /// <param name="graph">The enum value.</param>
        /// <param name="enumType">The EDM enum type of the value.</param>
        /// <param name="writeContext">The serializer write context.</param>
        /// <returns>The created <see cref="ODataEnumValue"/>.</returns>
        public virtual ODataEnumValue CreateODataEnumValue(object graph, IEdmEnumTypeReference enumType,
            ODataSerializerContext writeContext)
        {
            if (graph == null)
            {
                return null;
            }

            string value = null;
            if (graph.GetType().IsEnum)
            {
                value = graph.ToString();
            }
            else
            {
                if (graph.GetType() == typeof(EdmEnumObject))
                {
                    value = ((EdmEnumObject)graph).Value;
                }
            }

            ODataEnumValue enumValue = new ODataEnumValue(value, enumType.FullName());

            ODataMetadataLevel metadataLevel = writeContext != null
                ? writeContext.MetadataLevel
                : ODataMetadataLevel.MinimalMetadata;
            AddTypeNameAnnotationAsNeeded(enumValue, enumType, metadataLevel);

            return enumValue;
        }
        /// <inheritdoc />
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter,
            ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            IEdmNavigationSource navigationSource = writeContext.NavigationSource;
            if (navigationSource == null)
            {
                throw new SerializationException(SRResources.NavigationSourceMissingDuringSerialization);
            }

            var path = writeContext.Path;
            if (path == null)
            {
                throw new SerializationException(SRResources.ODataPathMissing);
            }

            ODataWriter writer = messageWriter.CreateODataEntryWriter(navigationSource, path.EdmType as IEdmEntityType);
            WriteObjectInline(graph, navigationSource.EntityType().ToEdmTypeReference(isNullable: false), writer, writeContext);
        }
        /// <summary>
        /// Creates an <see cref="ODataPrimitiveValue"/> for the object represented by <paramref name="graph"/>.
        /// </summary>
        /// <param name="graph">The primitive value.</param>
        /// <param name="primitiveType">The EDM primitive type of the value.</param>
        /// <param name="writeContext">The serializer write context.</param>
        /// <returns>The created <see cref="ODataPrimitiveValue"/>.</returns>
        public override ODataPrimitiveValue CreateODataPrimitiveValue(
            object graph,
            IEdmPrimitiveTypeReference primitiveType,
            ODataSerializerContext writeContext)
        {
            // The EDM type of the "graph" would override the EDM type of the property when
            // OData Web API infers the primitiveType. Thus for "graph" of System.DateTime,
            // the primitiveType is always Edm.DateTimeOffset.
            //
            // In EF, System.DateTime is used for SqlDate, SqlDateTime and SqlDateTime2.
            // All of them have no time zone information thus it is safe to clear the time
            // zone when converting the "graph" to a DateTimeOffset.
            if (primitiveType != null && primitiveType.IsDateTimeOffset() && graph is DateTime)
            {
                // If DateTime.Kind equals Local, offset should equal the offset of the system's local time zone
                if (((DateTime)graph).Kind == DateTimeKind.Local)
                {
                    graph = new DateTimeOffset((DateTime)graph, TimeZoneInfo.Local.GetUtcOffset((DateTime)graph));
                }
                else
                {
                    graph = new DateTimeOffset((DateTime)graph, TimeSpan.Zero);
                }
            }

            return base.CreateODataPrimitiveValue(graph, primitiveType, writeContext);
        }
        public void Apply_Doesnot_Override_UserConfiguration()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            var vehicles = builder.EntitySet<Vehicle>("vehicles");
            var car = builder.AddEntityType(typeof(Car));
            var paintAction = vehicles.EntityType.Action("Paint");
            paintAction.HasActionLink(ctxt => new Uri("http://localhost/ActionTestWorks"), followsConventions: false);
            ActionLinkGenerationConvention convention = new ActionLinkGenerationConvention();

            convention.Apply(paintAction, builder);

            IEdmModel model = builder.GetEdmModel();
            var vehiclesEdmSet = model.EntityContainer.FindEntitySet("vehicles");
            var carEdmType = model.FindDeclaredType("System.Web.OData.Builder.TestModels.Car") as IEdmEntityType;
            var paintEdmAction =
                model.GetAvailableProcedures(
                    model.FindDeclaredType("System.Web.OData.Builder.TestModels.Car") as IEdmEntityType).Single()
                as IEdmAction;
            Assert.NotNull(paintEdmAction);

            HttpConfiguration configuration = new HttpConfiguration();
            configuration.Routes.MapODataServiceRoute(model);

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost");
            request.SetConfiguration(configuration);

            ActionLinkBuilder actionLinkBuilder = model.GetActionLinkBuilder(paintEdmAction);

            var serializerContext = new ODataSerializerContext { Model = model, NavigationSource = vehiclesEdmSet, Url = request.GetUrlHelper() };
            var entityContext = new EntityInstanceContext(serializerContext, carEdmType.AsReference(), new Car { Model = 2009, Name = "Contoso" });

            Uri link = actionLinkBuilder.BuildActionLink(entityContext);
            Assert.Equal("http://localhost/ActionTestWorks", link.AbsoluteUri);
        }
        public void Ctor_ThatBuildsNestedContext_CopiesProperties()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataSerializerContext context = new ODataSerializerContext
            {
                NavigationSource = model.Customers,
                MetadataLevel = ODataMetadataLevel.FullMetadata,
                Model = model.Model,
                Path = new ODataPath(),
                Request = new HttpRequestMessage(),
                RootElementName = "somename",
                SelectExpandClause = new SelectExpandClause(new SelectItem[0], allSelected: true),
                SkipExpensiveAvailabilityChecks = true,
                Url = new UrlHelper()
            };
            EntityInstanceContext entity = new EntityInstanceContext { SerializerContext = context };
            SelectExpandClause selectExpand = new SelectExpandClause(new SelectItem[0], allSelected: true);
            IEdmNavigationProperty navProp = model.Customer.NavigationProperties().First();

            // Act
            ODataSerializerContext nestedContext = new ODataSerializerContext(entity, selectExpand, navProp);

            // Assert
            Assert.Equal(context.MetadataLevel, nestedContext.MetadataLevel);
            Assert.Same(context.Model, nestedContext.Model);
            Assert.Same(context.Path, nestedContext.Path);
            Assert.Same(context.Request, nestedContext.Request);
            Assert.Equal(context.RootElementName, nestedContext.RootElementName);
            Assert.Equal(context.SkipExpensiveAvailabilityChecks, nestedContext.SkipExpensiveAvailabilityChecks);
            Assert.Same(context.Url, nestedContext.Url);
        }
示例#17
0
        /// <inheritdoc />
        public override void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer,
            ODataSerializerContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }
            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }
            if (expectedType == null)
            {
                throw Error.ArgumentNull("expectedType");
            }
            if (graph == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, Feed));
            }

            IEnumerable enumerable = graph as IEnumerable; // Data to serialize
            if (enumerable == null)
            {
                throw new SerializationException(
                    Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
            }

            WriteFeed(enumerable, expectedType, writer, writeContext);
        }
        public void Convention_GeneratesUri_ForActionBoundToEntity()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Customer>("Customers");
            var action = builder.EntityType<Customer>().Action("MyAction");
            action.Parameter<string>("param");
            IEdmModel model = builder.GetEdmModel();

            // Act
            HttpConfiguration configuration = new HttpConfiguration();
            configuration.MapODataServiceRoute("odata", "odata", model);

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:123");
            request.SetConfiguration(configuration);
            request.ODataProperties().RouteName = "odata";

            IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");
            var edmType = model.SchemaElements.OfType<IEdmEntityType>().First(e => e.Name == "Customer");
            var serializerContext = new ODataSerializerContext { Model = model, NavigationSource = customers, Url = request.GetUrlHelper() };
            var entityContext = new EntityInstanceContext(serializerContext, edmType.AsReference(), new Customer { Id = 109 });

            // Assert
            var edmAction = model.SchemaElements.OfType<IEdmAction>().First(f => f.Name == "MyAction");
            Assert.NotNull(edmAction);

            ActionLinkBuilder actionLinkBuilder = model.GetActionLinkBuilder(edmAction);
            Uri link = actionLinkBuilder.BuildActionLink(entityContext);

            Assert.Equal("http://localhost:123/odata/Customers(109)/Default.MyAction", link.AbsoluteUri);
        }
示例#19
0
        /// <inheritdoc />
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;
            if (entitySet == null)
            {
                throw new SerializationException(SRResources.EntitySetMissingDuringSerialization);
            }

            IEdmTypeReference feedType = writeContext.GetEdmType(graph, type);
            Contract.Assert(feedType != null);

            IEdmEntityTypeReference entityType = GetEntityType(feedType);
            ODataWriter writer = messageWriter.CreateODataFeedWriter(entitySet, entityType.EntityDefinition());
            WriteObjectInline(graph, feedType, writer, writeContext);
        }
        /// <inheritdoc/>
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            if (graph != null)
            {
                ODataEntityReferenceLink entityReferenceLink = graph as ODataEntityReferenceLink;
                if (entityReferenceLink == null)
                {
                    Uri uri = graph as Uri;
                    if (uri == null)
                    {
                        throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
                    }

                    entityReferenceLink = new ODataEntityReferenceLink { Url = uri };
                }

                messageWriter.WriteEntityReferenceLink(entityReferenceLink);
            }
        }
示例#21
0
        /// <summary>
        /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties,
        /// navigation properties, and actions to select and expand for the given <paramref name="writeContext"/>.
        /// </summary>
        /// <param name="entityType">The entity type of the entry that would be written.</param>
        /// <param name="writeContext">The serializer context to be used while creating the collection.</param>
        /// <remarks>The default constructor is for unit testing only.</remarks>
        public SelectExpandNode(IEdmEntityType entityType, ODataSerializerContext writeContext)
            : this(writeContext.SelectExpandClause, entityType, writeContext.Model)
        {
            var queryOptionParser = new ODataQueryOptionParser(
                  writeContext.Model,
                  entityType,
                  writeContext.NavigationSource,
                  _extraQueryParameters);

            var selectExpandClause = queryOptionParser.ParseSelectAndExpand();
            if (selectExpandClause != null)
            {
                foreach (SelectItem selectItem in selectExpandClause.SelectedItems)
                {
                    ExpandedNavigationSelectItem expandItem = selectItem as ExpandedNavigationSelectItem;
                    if (expandItem != null)
                    {
                        ValidatePathIsSupported(expandItem.PathToNavigationProperty);
                        NavigationPropertySegment navigationSegment = (NavigationPropertySegment)expandItem.PathToNavigationProperty.LastSegment;
                        IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty;
                        if (!ExpandedNavigationProperties.ContainsKey(navigationProperty))
                        {
                            ExpandedNavigationProperties.Add(navigationProperty, expandItem.SelectAndExpand);
                        }
                    }
                }
            }
            SelectedNavigationProperties.ExceptWith(ExpandedNavigationProperties.Keys);
        }
        public void WriteObject_WritesValueReturnedFrom_CreateODataCollectionValue()
        {
            // Arrange
            MemoryStream stream = new MemoryStream();
            IODataResponseMessage message = new ODataMessageWrapper(stream);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings();
            settings.SetContentType(ODataFormat.Atom);
            ODataMessageWriter messageWriter = new ODataMessageWriter(message, settings);
            Mock<ODataCollectionSerializer> serializer = new Mock<ODataCollectionSerializer>(new DefaultODataSerializerProvider());
            ODataSerializerContext writeContext = new ODataSerializerContext { RootElementName = "CollectionName", Model = _model };
            IEnumerable enumerable = new object[0];
            ODataCollectionValue collectionValue = new ODataCollectionValue { TypeName = "NS.Name", Items = new[] { 0, 1, 2 } };

            serializer.CallBase = true;
            serializer
                .Setup(s => s.CreateODataCollectionValue(enumerable, It.Is<IEdmTypeReference>(e => e.Definition == _edmIntType.Definition), writeContext))
                .Returns(collectionValue).Verifiable();

            // Act
            serializer.Object.WriteObject(enumerable, typeof(int[]), messageWriter, writeContext);

            // Assert
            serializer.Verify();
            stream.Seek(0, SeekOrigin.Begin);
            XElement element = XElement.Load(stream);
            Assert.Equal("value", element.Name.LocalName);
            Assert.Equal(3, element.Descendants().Count());
            Assert.Equal(new[] { "0", "1", "2" }, element.Descendants().Select(e => e.Value));
        }
 public override void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
 {
     if (graph != null)
     {
         base.WriteObjectInline(graph, expectedType, writer, writeContext);
     }
 }
        /// <summary>
        /// Creates an <see cref="ODataPrimitiveValue"/> for the object represented by <paramref name="graph"/>.
        /// </summary>
        /// <param name="graph">The primitive value.</param>
        /// <param name="primitiveType">The EDM primitive type of the value.</param>
        /// <param name="writeContext">The serializer write context.</param>
        /// <returns>The created <see cref="ODataPrimitiveValue"/>.</returns>
        public virtual ODataPrimitiveValue CreateODataPrimitiveValue(object graph, IEdmPrimitiveTypeReference primitiveType,
            ODataSerializerContext writeContext)
        {
            ODataMetadataLevel metadataLevel = writeContext != null ? writeContext.MetadataLevel : ODataMetadataLevel.Default;

            // TODO: Bug 467598: validate the type of the object being passed in here with the underlying primitive type. 
            return CreatePrimitive(graph, primitiveType, metadataLevel);
        }
        public void WriteObject_Throws_RootElementNameMissing()
        {
            ODataSerializerContext writeContext = new ODataSerializerContext();
            ODataPrimitiveSerializer serializer = new ODataPrimitiveSerializer();

            Assert.Throws<ArgumentException>(
                () => serializer.WriteObject(42, typeof(int), ODataTestUtil.GetMockODataMessageWriter(), writeContext),
                "The 'RootElementName' property is required on 'ODataSerializerContext'.\r\nParameter name: writeContext");
        }
        /// <summary>
        /// Creates an <see cref="ODataComplexValue"/> for the object represented by <paramref name="graph"/>.
        /// </summary>
        /// <param name="graph">The value of the <see cref="ODataComplexValue"/> to be created.</param>
        /// <param name="complexType">The EDM complex type of the object.</param>
        /// <param name="writeContext">The serializer context.</param>
        /// <returns>The created <see cref="ODataComplexValue"/>.</returns>
        public virtual ODataComplexValue CreateODataComplexValue(object graph, IEdmComplexTypeReference complexType,
            ODataSerializerContext writeContext)
        {
            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            if (graph == null || graph is NullEdmComplexObject)
            {
                return null;
            }

            IEdmComplexObject complexObject = graph as IEdmComplexObject ?? new TypedEdmComplexObject(graph, complexType, writeContext.Model);

            List<ODataProperty> propertyCollection = new List<ODataProperty>();
            foreach (IEdmProperty property in complexType.ComplexDefinition().Properties())
            {
                IEdmTypeReference propertyType = property.Type;
                ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(propertyType);
                if (propertySerializer == null)
                {
                    throw Error.NotSupported(SRResources.TypeCannotBeSerialized, propertyType.FullName(), typeof(ODataMediaTypeFormatter).Name);
                }

                object propertyValue;
                if (complexObject.TryGetPropertyValue(property.Name, out propertyValue))
                {
                    propertyCollection.Add(
                        propertySerializer.CreateProperty(propertyValue, property.Type, property.Name, writeContext));
                }
            }

            // Try to add the dynamic properties if the complex type is open.
            if (complexType.ComplexDefinition().IsOpen)
            {
                List<ODataProperty> dynamicProperties = 
                    AppendDynamicProperties(complexObject, complexType, writeContext, propertyCollection);

                if (dynamicProperties != null)
                {
                    propertyCollection.AddRange(dynamicProperties);
                }
            }

            string typeName = complexType.FullName();

            ODataComplexValue value = new ODataComplexValue()
            {
                Properties = propertyCollection,
                TypeName = typeName
            };

            AddTypeNameAnnotationAsNeeded(value, writeContext.MetadataLevel);
            return value;
        }
        public void WriteObject_Throws_ODataPathMissing()
        {
            ODataEntityReferenceLinksSerializer serializer = new ODataEntityReferenceLinksSerializer();
            ODataSerializerContext writeContext = new ODataSerializerContext { EntitySet = _customerSet };

            Assert.Throws<SerializationException>(
                () => serializer.WriteObject(graph: null, type: typeof(ODataEntityReferenceLinks),
                    messageWriter: ODataTestUtil.GetMockODataMessageWriter(), writeContext: writeContext),
                "The operation cannot be completed because no ODataPath is available for the request.");
        }
        public void GenerateSelfLink_GeneratesExpectedSelfLink(bool includeCast, string expectedIdLink)
        {
            HttpRequestMessage request = GetODataRequest(_model.Model);
            var serializerContext = new ODataSerializerContext { Model = _model.Model, EntitySet = _model.Customers, Url = request.GetUrlHelper() };
            var entityContext = new EntityInstanceContext(serializerContext, _model.SpecialCustomer.AsReference(), new { ID = 42 });

            string idLink = entityContext.GenerateSelfLink(includeCast);

            Assert.Equal(expectedIdLink, idLink);
        }
        public void WriteObject_Throws_NavigationPropertyMissingDuringSerialization()
        {
            ODataEntityReferenceLinksSerializer serializer = new ODataEntityReferenceLinksSerializer();
            ODataSerializerContext writeContext = new ODataSerializerContext { EntitySet = _customerSet, Path = new ODataPath() };

            Assert.Throws<SerializationException>(
                () => serializer.WriteObject(graph: null, type: typeof(ODataEntityReferenceLinks),
                    messageWriter: ODataTestUtil.GetMockODataMessageWriter(), writeContext: writeContext),
                "The related navigation property could not be found from the OData path. The related navigation property is required to serialize the payload.");
        }
 internal ODataProperty CreateProperty(object graph, IEdmTypeReference expectedType, string elementName,
     ODataSerializerContext writeContext)
 {
     Contract.Assert(elementName != null);
     return new ODataProperty
     {
         Name = elementName,
         Value = CreateODataValue(graph, expectedType, writeContext)
     };
 }
 /// <summary>
 /// Writes the given object 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="expectedType">The expected EDM type of the object represented by <paramref name="graph"/>.</param>
 /// <param name="writer">The <see cref="ODataWriter" /> to be used for writing.</param>
 /// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
 public virtual void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer,
                                       ODataSerializerContext writeContext)
 {
     throw Error.NotSupported(SRResources.WriteObjectInlineNotSupported, GetType().Name);
 }
示例#32
0
 /// <summary>
 /// Creates an <see cref="ODataPrimitiveValue"/> for the object represented by <paramref name="graph"/>.
 /// </summary>
 /// <param name="graph">The primitive value.</param>
 /// <param name="primitiveType">The EDM primitive type of the value.</param>
 /// <param name="writeContext">The serializer write context.</param>
 /// <returns>The created <see cref="ODataPrimitiveValue"/>.</returns>
 public virtual ODataPrimitiveValue CreateODataPrimitiveValue(object graph, IEdmPrimitiveTypeReference primitiveType,
                                                              ODataSerializerContext writeContext)
 {
     // TODO: Bug 467598: validate the type of the object being passed in here with the underlying primitive type.
     return(CreatePrimitive(graph, primitiveType, writeContext));
 }
示例#33
0
        /// <summary>
        /// Create the <see cref="ODataFeed"/> to be written for the given feed instance.
        /// </summary>
        /// <param name="feedInstance">The instance representing the feed being written.</param>
        /// <param name="feedType">The EDM type of the feed being written.</param>
        /// <param name="writeContext">The serializer context.</param>
        /// <returns>The created <see cref="ODataFeed"/> object.</returns>
        public virtual ODataFeed CreateODataFeed(IEnumerable feedInstance, IEdmCollectionTypeReference feedType,
                                                 ODataSerializerContext writeContext)
        {
            ODataFeed feed = new ODataFeed();

            if (writeContext.EntitySet != null)
            {
                IEdmModel model = writeContext.Model;
                EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(writeContext.EntitySet);
                FeedContext feedContext = new FeedContext
                {
                    Request        = writeContext.Request,
                    RequestContext = writeContext.RequestContext,
                    EntitySet      = writeContext.EntitySet,
                    Url            = writeContext.Url,
                    FeedInstance   = feedInstance
                };

                Uri feedSelfLink = linkBuilder.BuildFeedSelfLink(feedContext);
                if (feedSelfLink != null)
                {
                    feed.SetAnnotation(new AtomFeedMetadata()
                    {
                        SelfLink = new AtomLinkMetadata()
                        {
                            Relation = "self", Href = feedSelfLink
                        }
                    });
                }
            }

            feed.Id = new Uri("http://schemas.datacontract.org/2004/07/" + feedType.FullName());

            if (writeContext.ExpandedEntity == null)
            {
                // If we have more OData format specific information apply it now, only if we are the root feed.
                PageResult odataFeedAnnotations = feedInstance as PageResult;
                if (odataFeedAnnotations != null)
                {
                    feed.Count        = odataFeedAnnotations.Count;
                    feed.NextPageLink = odataFeedAnnotations.NextPageLink;
                }
                else if (writeContext.Request != null)
                {
                    feed.NextPageLink = writeContext.Request.ODataProperties().NextLink;

                    long?countValue = writeContext.Request.ODataProperties().TotalCount;
                    if (countValue.HasValue)
                    {
                        feed.Count = countValue.Value;
                    }
                }
            }
            else
            {
                // nested feed
                ITruncatedCollection truncatedCollection = feedInstance as ITruncatedCollection;
                if (truncatedCollection != null && truncatedCollection.IsTruncated)
                {
                    feed.NextPageLink = GetNestedNextPageLink(writeContext, truncatedCollection.PageSize);
                }
            }

            return(feed);
        }
示例#34
0
        internal List <ODataProperty> AppendDynamicProperties(object source, IEdmStructuredTypeReference structuredType,
                                                              ODataSerializerContext writeContext, List <ODataProperty> declaredProperties,
                                                              string[] selectedDynamicProperties)
        {
            Contract.Assert(source != null);
            Contract.Assert(structuredType != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(writeContext.Model != null);

            bool nullDynamicPropertyEnabled = false;

            if (source is EdmDeltaComplexObject || source is EdmDeltaEntityObject)
            {
                nullDynamicPropertyEnabled = true;
            }
            else if (writeContext.Request != null)
            {
                HttpConfiguration configuration = writeContext.Request.GetConfiguration();
                if (configuration != null)
                {
                    nullDynamicPropertyEnabled = configuration.HasEnabledNullDynamicProperty();
                }
            }

            PropertyInfo dynamicPropertyInfo = EdmLibHelpers.GetDynamicPropertyDictionary(
                structuredType.StructuredDefinition(), writeContext.Model);

            IEdmStructuredObject structuredObject = source as IEdmStructuredObject;
            object value;
            IDelta delta = source as IDelta;

            if (delta == null)
            {
                if (dynamicPropertyInfo == null || structuredObject == null ||
                    !structuredObject.TryGetPropertyValue(dynamicPropertyInfo.Name, out value) || value == null)
                {
                    return(null);
                }
            }
            else
            {
                value = ((EdmStructuredObject)structuredObject).TryGetDynamicProperties();
            }

            IDictionary <string, object> dynamicPropertyDictionary = (IDictionary <string, object>)value;

            // Build a HashSet to store the declared property names.
            // It is used to make sure the dynamic property name is different from all declared property names.
            HashSet <string>     declaredPropertyNameSet = new HashSet <string>(declaredProperties.Select(p => p.Name));
            List <ODataProperty> dynamicProperties       = new List <ODataProperty>();
            IEnumerable <KeyValuePair <string, object> > dynamicPropertiesToSelect =
                dynamicPropertyDictionary.Where(
                    x => !selectedDynamicProperties.Any() || selectedDynamicProperties.Contains(x.Key));

            foreach (KeyValuePair <string, object> dynamicProperty in dynamicPropertiesToSelect)
            {
                if (String.IsNullOrEmpty(dynamicProperty.Key))
                {
                    continue;
                }

                if (dynamicProperty.Value == null)
                {
                    if (nullDynamicPropertyEnabled)
                    {
                        dynamicProperties.Add(new ODataProperty
                        {
                            Name  = dynamicProperty.Key,
                            Value = new ODataNullValue()
                        });
                    }

                    continue;
                }

                if (declaredPropertyNameSet.Contains(dynamicProperty.Key))
                {
                    throw Error.InvalidOperation(SRResources.DynamicPropertyNameAlreadyUsedAsDeclaredPropertyName,
                                                 dynamicProperty.Key, structuredType.FullName());
                }

                IEdmTypeReference edmTypeReference = writeContext.GetEdmType(dynamicProperty.Value,
                                                                             dynamicProperty.Value.GetType());
                if (edmTypeReference == null)
                {
                    throw Error.NotSupported(SRResources.TypeOfDynamicPropertyNotSupported,
                                             dynamicProperty.Value.GetType().FullName, dynamicProperty.Key);
                }

                ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(edmTypeReference);
                if (propertySerializer == null)
                {
                    throw Error.NotSupported(SRResources.DynamicPropertyCannotBeSerialized, dynamicProperty.Key,
                                             edmTypeReference.FullName());
                }

                dynamicProperties.Add(propertySerializer.CreateProperty(
                                          dynamicProperty.Value, edmTypeReference, dynamicProperty.Key, writeContext));
            }

            return(dynamicProperties);
        }
示例#35
0
        /// <summary>
        /// Create the <see cref="ODataResourceSet"/> to be written for the given resourceSet instance.
        /// </summary>
        /// <param name="resourceSetInstance">The instance representing the resourceSet being written.</param>
        /// <param name="resourceSetType">The EDM type of the resourceSet being written.</param>
        /// <param name="writeContext">The serializer context.</param>
        /// <returns>The created <see cref="ODataResourceSet"/> object.</returns>
        public virtual ODataResourceSet CreateResourceSet(IEnumerable resourceSetInstance, IEdmCollectionTypeReference resourceSetType,
                                                          ODataSerializerContext writeContext)
        {
            ODataResourceSet resourceSet = new ODataResourceSet
            {
                TypeName = resourceSetType.FullName()
            };

            IEdmStructuredTypeReference structuredType = GetResourceType(resourceSetType).AsStructured();

            if (writeContext.NavigationSource != null && structuredType.IsEntity())
            {
                ResourceSetContext resourceSetContext = new ResourceSetContext
                {
                    Request             = writeContext.Request,
                    RequestContext      = writeContext.RequestContext,
                    EntitySetBase       = writeContext.NavigationSource as IEdmEntitySetBase,
                    Url                 = writeContext.Url,
                    ResourceSetInstance = resourceSetInstance
                };

                IEdmEntityType entityType      = structuredType.AsEntity().EntityDefinition();
                var            operations      = writeContext.Model.GetAvailableOperationsBoundToCollection(entityType);
                var            odataOperations = CreateODataOperations(operations, resourceSetContext, writeContext);
                foreach (var odataOperation in odataOperations)
                {
                    ODataAction action = odataOperation as ODataAction;
                    if (action != null)
                    {
                        resourceSet.AddAction(action);
                    }
                    else
                    {
                        resourceSet.AddFunction((ODataFunction)odataOperation);
                    }
                }
            }

            if (writeContext.ExpandedResource == null)
            {
                // If we have more OData format specific information apply it now, only if we are the root feed.
                PageResult odataResourceSetAnnotations = resourceSetInstance as PageResult;
                if (odataResourceSetAnnotations != null)
                {
                    resourceSet.Count        = odataResourceSetAnnotations.Count;
                    resourceSet.NextPageLink = odataResourceSetAnnotations.NextPageLink;
                }
                else if (writeContext.Request != null)
                {
                    resourceSet.NextPageLink = writeContext.Request.ODataProperties().NextLink;
                    resourceSet.DeltaLink    = writeContext.Request.ODataProperties().DeltaLink;

                    long?countValue = writeContext.Request.ODataProperties().TotalCount;
                    if (countValue.HasValue)
                    {
                        resourceSet.Count = countValue.Value;
                    }
                }
            }
            else
            {
                // nested resourceSet
                ITruncatedCollection truncatedCollection = resourceSetInstance as ITruncatedCollection;
                if (truncatedCollection != null && truncatedCollection.IsTruncated)
                {
                    resourceSet.NextPageLink = GetNestedNextPageLink(writeContext, truncatedCollection.PageSize);
                }

                ICountOptionCollection countOptionCollection = resourceSetInstance as ICountOptionCollection;
                if (countOptionCollection != null && countOptionCollection.TotalCount != null)
                {
                    resourceSet.Count = countOptionCollection.TotalCount;
                }
            }

            return(resourceSet);
        }
示例#36
0
        /// <summary>
        /// Writes the given deltaDeletedLink 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 WriteDeltaDeletedLink(object graph, ODataDeltaWriter writer, ODataSerializerContext writeContext)
        {
            EdmDeltaDeletedLink edmDeltaDeletedLink = graph as EdmDeltaDeletedLink;

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

            ODataDeltaDeletedLink deltaDeletedLink = new ODataDeltaDeletedLink(
                edmDeltaDeletedLink.Source,
                edmDeltaDeletedLink.Target,
                edmDeltaDeletedLink.Relationship);

            if (deltaDeletedLink != null)
            {
                writer.WriteDeltaDeletedLink(deltaDeletedLink);
            }
        }
示例#37
0
 /// <summary>
 /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties,
 /// nested properties, navigation properties, and actions to select and expand for the given <paramref name="writeContext"/>.
 /// </summary>
 /// <param name="structuredType">The structural type of the resource that would be written.</param>
 /// <param name="writeContext">The serializer context to be used while creating the collection.</param>
 /// <remarks>The default constructor is for unit testing only.</remarks>
 public SelectExpandNode(IEdmStructuredType structuredType, ODataSerializerContext writeContext)
     : this(writeContext.SelectExpandClause, structuredType, writeContext.Model)
 {
 }
示例#38
0
        private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataDeltaWriter writer,
                               ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(feedType != null);

            ODataDeltaFeed deltaFeed = CreateODataDeltaFeed(enumerable, feedType.AsCollection(), writeContext);

            if (deltaFeed == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
            }

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = deltaFeed.NextPageLink;

            deltaFeed.NextPageLink = null;

            //Start writing of the Delta Feed
            writer.WriteStart(deltaFeed);

            //Iterate over all the entries present and select the appropriate write method.
            //Write method creates ODataDeltaDeletedEntry / ODataDeltaDeletedLink / ODataDeltaLink or ODataEntry.
            foreach (object entry in enumerable)
            {
                if (entry == null)
                {
                    throw new SerializationException(SRResources.NullElementInCollection);
                }

                IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
                if (edmChangedObject == null)
                {
                    throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
                }

                switch (edmChangedObject.DeltaKind)
                {
                case EdmDeltaEntityKind.DeletedEntry:
                    WriteDeltaDeletedEntry(entry, writer, writeContext);
                    break;

                case EdmDeltaEntityKind.DeletedLinkEntry:
                    WriteDeltaDeletedLink(entry, writer, writeContext);
                    break;

                case EdmDeltaEntityKind.LinkEntry:
                    WriteDeltaLink(entry, writer, writeContext);
                    break;

                case EdmDeltaEntityKind.Entry:
                {
                    IEdmEntityTypeReference   elementType     = GetEntityType(feedType);
                    ODataEntityTypeSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataEntityTypeSerializer;
                    if (entrySerializer == null)
                    {
                        throw new SerializationException(
                                  Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name));
                    }
                    entrySerializer.WriteDeltaObjectInline(entry, elementType, writer, writeContext);
                    break;
                }

                default:
                    break;
                }
            }

            // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(feed),
            // 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(feed) but is instead set later on that feed
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.
            if (nextPageLink != null)
            {
                deltaFeed.NextPageLink = nextPageLink;
            }

            //End Writing of the Delta Feed
            writer.WriteEnd();
        }
示例#39
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, ODataDeltaWriter writer, ODataSerializerContext writeContext)
        {
            EdmDeltaDeletedEntityObject edmDeltaDeletedEntity = graph as EdmDeltaDeletedEntityObject;

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

            ODataDeltaDeletedEntry deltaDeletedEntry = new ODataDeltaDeletedEntry(
                edmDeltaDeletedEntity.Id, edmDeltaDeletedEntity.Reason);

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

            if (deltaDeletedEntry != null)
            {
                writer.WriteDeltaDeletedEntry(deltaDeletedEntry);
            }
        }
        /// <inheritdoc/>
        /// <remarks>The metadata written is from the model set on the <paramref name="messageWriter"/>. The <paramref name="graph" />
        /// is not used.</remarks>
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            // NOTE: ODataMessageWriter doesn't have a way to set the IEdmModel. So, there is an underlying assumption here that
            // the model received by this method and the model passed(from configuration) while building ODataMessageWriter is the same (clr object).
            messageWriter.WriteMetadataDocument();
        }
        public void CreateODataComplexValue_WritesAllDeclaredAndDynamicProperties_ForOpenComplexType()
        {
            // Arrange
            IEdmModel model = SerializationTestsHelpers.SimpleOpenTypeModel();

            IEdmComplexType addressType       = model.FindDeclaredType("Default.Address") as IEdmComplexType;
            Type            simpleOpenAddress = typeof(SimpleOpenAddress);

            model.SetAnnotationValue <ClrTypeAnnotation>(addressType, new ClrTypeAnnotation(simpleOpenAddress));

            IEdmEnumType enumType       = model.FindDeclaredType("Default.SimpleEnum") as IEdmEnumType;
            Type         simpleEnumType = typeof(SimpleEnum);

            model.SetAnnotationValue <ClrTypeAnnotation>(enumType, new ClrTypeAnnotation(simpleEnumType));

            model.SetAnnotationValue(addressType, new DynamicPropertyDictionaryAnnotation(
                                         simpleOpenAddress.GetProperty("Properties")));

            IEdmComplexTypeReference addressTypeRef = addressType.ToEdmTypeReference(isNullable: false).AsComplex();

            ODataSerializerProvider    serializerProvider = new DefaultODataSerializerProvider();
            ODataComplexTypeSerializer serializer         = new ODataComplexTypeSerializer(serializerProvider);
            ODataSerializerContext     context            = new ODataSerializerContext
            {
                Model = model
            };

            SimpleOpenAddress address = new SimpleOpenAddress()
            {
                Street     = "My Way",
                City       = "Redmond",
                Properties = new Dictionary <string, object>()
            };

            address.Properties.Add("EnumProperty", SimpleEnum.Fourth);
            address.Properties.Add("GuidProperty", new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"));
            address.Properties.Add("DoubleProperty", 99.109);
            address.Properties.Add("DateTimeProperty", new DateTime(2014, 10, 27));

            // Act
            var odataValue = serializer.CreateODataComplexValue(address, addressTypeRef, context);

            // Assert
            ODataComplexValue complexValue = Assert.IsType <ODataComplexValue>(odataValue);

            Assert.Equal(complexValue.TypeName, "Default.Address");
            Assert.Equal(6, complexValue.Properties.Count());

            // Verify the declared properties
            ODataProperty street = Assert.Single(complexValue.Properties.Where(p => p.Name == "Street"));

            Assert.Equal("My Way", street.Value);

            ODataProperty city = Assert.Single(complexValue.Properties.Where(p => p.Name == "City"));

            Assert.Equal("Redmond", city.Value);

            // Verify the dynamic properties
            ODataProperty  enumProperty = Assert.Single(complexValue.Properties.Where(p => p.Name == "EnumProperty"));
            ODataEnumValue enumValue    = Assert.IsType <ODataEnumValue>(enumProperty.Value);

            Assert.Equal("Fourth", enumValue.Value);
            Assert.Equal("Default.SimpleEnum", enumValue.TypeName);

            ODataProperty guidProperty = Assert.Single(complexValue.Properties.Where(p => p.Name == "GuidProperty"));

            Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), guidProperty.Value);

            ODataProperty doubleProperty = Assert.Single(complexValue.Properties.Where(p => p.Name == "DoubleProperty"));

            Assert.Equal(99.109, doubleProperty.Value);

            ODataProperty dateTimeProperty =
                Assert.Single(complexValue.Properties.Where(p => p.Name == "DateTimeProperty"));

            Assert.Equal(new DateTimeOffset(new DateTime(2014, 10, 27)), dateTimeProperty.Value);
        }
示例#42
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);
            ODataResourceSet            resourceSet = CreateResourceSet(enumerable, resourceSetType.AsCollection(), writeContext);

            if (resourceSet == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, ResourceSet));
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                resourceSet.SetSerializationInfo(new ODataResourceSerializationInfo
                {
                    IsFromCollection = true,
                    NavigationSourceEntityTypeName = elementType.FullName(),
                    NavigationSourceKind           = EdmNavigationSourceKind.UnknownEntitySet,
                    NavigationSourceName           = null
                });
            }

            ODataEdmTypeSerializer resourceSerializer = SerializerProvider.GetEdmTypeSerializer(elementType);

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

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = resourceSet.NextPageLink;

            resourceSet.NextPageLink = null;

            writer.WriteStart(resourceSet);

            foreach (object item in enumerable)
            {
                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.

            if (nextPageLink != null)
            {
                resourceSet.NextPageLink = nextPageLink;
            }

            writer.WriteEnd();
        }
示例#43
0
        /// <inheritdoc />
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            IEdmTypeReference resourceSetType = writeContext.GetEdmType(graph, type);

            Contract.Assert(resourceSetType != null);

            IEdmStructuredTypeReference resourceType = GetResourceType(resourceSetType);
            ODataWriter writer = messageWriter.CreateODataResourceSetWriter(entitySet, resourceType.StructuredDefinition());

            WriteObjectInline(graph, resourceSetType, writer, writeContext);
        }
示例#44
0
        /// <inheritdoc/>
        public sealed override ODataValue CreateODataValue(object graph, IEdmTypeReference expectedType, ODataSerializerContext writeContext)
        {
            if (!expectedType.IsEnum())
            {
                throw Error.InvalidOperation(SRResources.CannotWriteType, typeof(ODataEnumSerializer).Name, expectedType.FullName());
            }

            ODataEnumValue value = CreateODataEnumValue(graph, expectedType.AsEnum(), writeContext);

            if (value == null)
            {
                return(new ODataNullValue());
            }

            return(value);
        }
 /// <summary>
 /// Creates an <see cref="ODataValue"/> for the object represented by <paramref name="graph"/>.
 /// </summary>
 /// <param name="graph">The value of the <see cref="ODataValue"/> to be created.</param>
 /// <param name="expectedType">The expected EDM type of the object represented by <paramref name="graph"/>.</param>
 /// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
 /// <returns>The <see cref="ODataValue"/> created.</returns>
 public virtual ODataValue CreateODataValue(object graph, IEdmTypeReference expectedType, ODataSerializerContext writeContext)
 {
     throw Error.NotSupported(SRResources.CreateODataValueNotSupported, GetType().Name);
 }
示例#46
0
        private IEnumerable <ODataOperation> CreateODataOperations(IEnumerable <IEdmOperation> operations, ResourceSetContext resourceSetContext, ODataSerializerContext writeContext)
        {
            Contract.Assert(operations != null);
            Contract.Assert(resourceSetContext != null);
            Contract.Assert(writeContext != null);

            foreach (IEdmOperation operation in operations)
            {
                ODataOperation oDataOperation = CreateODataOperation(operation, resourceSetContext, writeContext);
                if (oDataOperation != null)
                {
                    yield return(oDataOperation);
                }
            }
        }
示例#47
0
        /// <inheritdoc/>
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }
            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }
            if (writeContext.RootElementName == null)
            {
                throw Error.Argument("writeContext", SRResources.RootElementNameMissing, typeof(ODataSerializerContext).Name);
            }

            IEdmTypeReference edmType = writeContext.GetEdmType(graph, type);

            Contract.Assert(edmType != null);

            messageWriter.WriteProperty(CreateProperty(graph, edmType, writeContext.RootElementName, writeContext));
        }
示例#48
0
        public virtual ODataOperation CreateODataOperation(IEdmOperation operation, ResourceSetContext resourceSetContext, ODataSerializerContext writeContext)
        {
            if (operation == null)
            {
                throw Error.ArgumentNull("operation");
            }

            if (resourceSetContext == null)
            {
                throw Error.ArgumentNull("resourceSetContext");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            ODataMetadataLevel metadataLevel = writeContext.MetadataLevel;
            IEdmModel          model         = writeContext.Model;

            if (metadataLevel != ODataMetadataLevel.FullMetadata)
            {
                return(null);
            }

            OperationLinkBuilder builder;

            builder = model.GetOperationLinkBuilder(operation);

            if (builder == null)
            {
                return(null);
            }

            Uri target = builder.BuildLink(resourceSetContext);

            if (target == null)
            {
                return(null);
            }

            Uri baseUri  = new Uri(writeContext.Url.CreateODataLink(MetadataSegment.Instance));
            Uri metadata = new Uri(baseUri, "#" + operation.FullName());

            ODataOperation odataOperation;
            IEdmAction     action = operation as IEdmAction;

            if (action != null)
            {
                odataOperation = new ODataAction();
            }
            else
            {
                odataOperation = new ODataFunction();
            }
            odataOperation.Metadata = metadata;

            // Always omit the title in minimal/no metadata modes.
            ODataResourceSerializer.EmitTitle(model, operation, odataOperation);

            // Omit the target in minimal/no metadata modes unless it doesn't follow conventions.
            if (metadataLevel == ODataMetadataLevel.FullMetadata || !builder.FollowsConventions)
            {
                odataOperation.Target = target;
            }

            return(odataOperation);
        }
示例#49
0
        /// <summary>
        /// Creates an <see cref="ODataComplexValue"/> for the object represented by <paramref name="graph"/>.
        /// </summary>
        /// <param name="graph">The value of the <see cref="ODataComplexValue"/> to be created.</param>
        /// <param name="complexType">The EDM complex type of the object.</param>
        /// <param name="writeContext">The serializer context.</param>
        /// <returns>The created <see cref="ODataComplexValue"/>.</returns>
        public virtual ODataComplexValue CreateODataComplexValue(object graph, IEdmComplexTypeReference complexType,
                                                                 ODataSerializerContext writeContext)
        {
            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            if (graph == null || graph is NullEdmComplexObject)
            {
                return(null);
            }

            IEdmComplexObject   complexObject      = graph as IEdmComplexObject ?? new TypedEdmComplexObject(graph, complexType, writeContext.Model);
            List <IEdmProperty> settableProperties = new List <IEdmProperty>(complexType.ComplexDefinition().Properties());

            if (complexObject.IsDeltaResource())
            {
                IDelta deltaProperty = graph as IDelta;
                Contract.Assert(deltaProperty != null);
                IEnumerable <string> changedProperties = deltaProperty.GetChangedPropertyNames();
                settableProperties = settableProperties.Where(p => changedProperties.Contains(p.Name)).ToList();
            }
            List <ODataProperty> propertyCollection = new List <ODataProperty>();

            foreach (IEdmProperty property in settableProperties)
            {
                IEdmTypeReference      propertyType       = property.Type;
                ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(propertyType);
                if (propertySerializer == null)
                {
                    throw Error.NotSupported(SRResources.TypeCannotBeSerialized, propertyType.FullName(), typeof(ODataMediaTypeFormatter).Name);
                }

                object propertyValue;
                if (complexObject.TryGetPropertyValue(property.Name, out propertyValue))
                {
                    if (propertyValue != null && propertyType != null && propertyType.IsComplex())
                    {
                        IEdmTypeReference actualType = writeContext.GetEdmType(propertyValue, propertyValue.GetType());
                        if (actualType != null && propertyType != actualType)
                        {
                            propertyType = actualType;
                        }
                    }
                    var odataProperty = propertySerializer.CreateProperty(propertyValue, propertyType, property.Name,
                                                                          writeContext);
                    if (odataProperty != null)
                    {
                        propertyCollection.Add(odataProperty);
                    }
                }
            }

            // Try to add the dynamic properties if the complex type is open.
            if (complexType.ComplexDefinition().IsOpen)
            {
                List <ODataProperty> dynamicProperties =
                    AppendDynamicProperties(complexObject, complexType, writeContext, propertyCollection, new string[0]);

                if (dynamicProperties != null)
                {
                    propertyCollection.AddRange(dynamicProperties);
                }
            }

            string typeName = complexType.FullName();

            ODataComplexValue value = new ODataComplexValue()
            {
                Properties = propertyCollection,
                TypeName   = typeName
            };

            AddTypeNameAnnotationAsNeeded(value, writeContext.MetadataLevel);
            return(value);
        }
        public void Property_Items_IsInitialized()
        {
            ODataSerializerContext context = new ODataSerializerContext();

            Assert.NotNull(context.Items);
        }
示例#51
0
        /// <summary>
        /// Creates an <see cref="ODataCollectionValue"/> for the enumerable represented by <paramref name="enumerable"/>.
        /// </summary>
        /// <param name="enumerable">The value of the collection to be created.</param>
        /// <param name="elementType">The element EDM type of the collection.</param>
        /// <param name="writeContext">The serializer context to be used while creating the collection.</param>
        /// <returns>The created <see cref="ODataCollectionValue"/>.</returns>
        public virtual ODataCollectionValue CreateODataCollectionValue(IEnumerable enumerable, IEdmTypeReference elementType,
                                                                       ODataSerializerContext writeContext)
        {
            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }
            if (elementType == null)
            {
                throw Error.ArgumentNull("elementType");
            }

            ArrayList valueCollection = new ArrayList();

            if (enumerable != null)
            {
                ODataEdmTypeSerializer itemSerializer = null;
                foreach (object item in enumerable)
                {
                    if (item == null)
                    {
                        if (elementType.IsNullable)
                        {
                            valueCollection.Add(value: null);
                            continue;
                        }

                        throw new SerializationException(SRResources.NullElementInCollection);
                    }

                    IEdmTypeReference actualType = writeContext.GetEdmType(item, item.GetType());
                    Contract.Assert(actualType != null);

                    itemSerializer = itemSerializer ?? SerializerProvider.GetEdmTypeSerializer(actualType);
                    if (itemSerializer == null)
                    {
                        throw new SerializationException(
                                  Error.Format(SRResources.TypeCannotBeSerialized, actualType.FullName(),
                                               typeof(ODataMediaTypeFormatter).Name));
                    }

                    // ODataCollectionWriter expects the individual elements in the collection to be the underlying
                    // values and not ODataValues.
                    valueCollection.Add(
                        itemSerializer.CreateODataValue(item, actualType, writeContext).GetInnerValue());
                }
            }

            // Ideally, we'd like to do this:
            // string typeName = _edmCollectionType.FullName();
            // But ODataLib currently doesn't support .FullName() for collections. As a workaround, we construct the
            // collection type name the hard way.
            string typeName = "Collection(" + elementType.FullName() + ")";

            // ODataCollectionValue is only a V3 property, arrays inside Complex Types or Entity types are only supported in V3
            // if a V1 or V2 Client requests a type that has a collection within it ODataLib will throw.
            ODataCollectionValue value = new ODataCollectionValue
            {
                Items    = valueCollection,
                TypeName = typeName
            };

            AddTypeNameAnnotationAsNeeded(value, writeContext.MetadataLevel);
            return(value);
        }
        /// <inheridoc />
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            IEdmEntitySet entitySet = writeContext.EntitySet;

            if (entitySet == null)
            {
                throw new SerializationException(SRResources.EntitySetMissingDuringSerialization);
            }

            if (writeContext.Path == null)
            {
                throw new SerializationException(SRResources.ODataPathMissing);
            }

            IEdmNavigationProperty navigationProperty = writeContext.Path.GetNavigationProperty();

            if (navigationProperty == null)
            {
                throw new SerializationException(SRResources.NavigationPropertyMissingDuringSerialization);
            }

            if (graph != null)
            {
                ODataEntityReferenceLinks entityReferenceLinks = graph as ODataEntityReferenceLinks;
                if (entityReferenceLinks == null)
                {
                    IEnumerable <Uri> uris = graph as IEnumerable <Uri>;
                    if (uris == null)
                    {
                        throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
                    }

                    entityReferenceLinks = new ODataEntityReferenceLinks
                    {
                        Links = uris.Select(uri => new ODataEntityReferenceLink {
                            Url = uri
                        })
                    };
                }

                messageWriter.WriteEntityReferenceLinks(entityReferenceLinks, entitySet, navigationProperty);
            }
        }
        public void CreateODataComplexValue_WritesDynamicCollectionProperty_ForOpenComplexType()
        {
            // Arrange
            IEdmModel model = SerializationTestsHelpers.SimpleOpenTypeModel();

            IEdmComplexType addressType       = model.FindDeclaredType("Default.Address") as IEdmComplexType;
            Type            simpleOpenAddress = typeof(SimpleOpenAddress);

            model.SetAnnotationValue <ClrTypeAnnotation>(addressType, new ClrTypeAnnotation(simpleOpenAddress));

            IEdmEnumType enumType       = model.FindDeclaredType("Default.SimpleEnum") as IEdmEnumType;
            Type         simpleEnumType = typeof(SimpleEnum);

            model.SetAnnotationValue <ClrTypeAnnotation>(enumType, new ClrTypeAnnotation(simpleEnumType));

            model.SetAnnotationValue(addressType, new DynamicPropertyDictionaryAnnotation(
                                         simpleOpenAddress.GetProperty("Properties")));

            IEdmComplexTypeReference addressTypeRef = addressType.ToEdmTypeReference(isNullable: false).AsComplex();

            ODataSerializerProvider    serializerProvider = new DefaultODataSerializerProvider();
            ODataComplexTypeSerializer serializer         = new ODataComplexTypeSerializer(serializerProvider);
            ODataSerializerContext     context            = new ODataSerializerContext
            {
                Model = model
            };

            SimpleOpenAddress address = new SimpleOpenAddress()
            {
                Street     = "One Way",
                City       = "One City",
                Properties = new Dictionary <string, object>()
            };

            address.Properties.Add("CollectionProperty", new[] { 1.1, 2.2 });

            // Act
            var odataValue = serializer.CreateODataComplexValue(address, addressTypeRef, context);

            // Assert
            ODataComplexValue complexValue = Assert.IsType <ODataComplexValue>(odataValue);

            Assert.Equal(complexValue.TypeName, "Default.Address");
            Assert.Equal(3, complexValue.Properties.Count());

            // Verify the declared properties
            ODataProperty street = Assert.Single(complexValue.Properties.Where(p => p.Name == "Street"));

            Assert.Equal("One Way", street.Value);

            ODataProperty city = Assert.Single(complexValue.Properties.Where(p => p.Name == "City"));

            Assert.Equal("One City", city.Value);

            // Verify the dynamic properties
            ODataProperty        enumProperty    = Assert.Single(complexValue.Properties.Where(p => p.Name == "CollectionProperty"));
            ODataCollectionValue collectionValue = Assert.IsType <ODataCollectionValue>(enumProperty.Value);

            Assert.Equal("Collection(Edm.Double)", collectionValue.TypeName);
            Assert.Equal(new List <double> {
                1.1, 2.2
            }, collectionValue.Items.OfType <double>().ToList());
        }
示例#54
0
        /// <inheritdoc/>
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            if (graph != null)
            {
                ODataEntityReferenceLink entityReferenceLink = graph as ODataEntityReferenceLink;
                if (entityReferenceLink == null)
                {
                    Uri uri = graph as Uri;
                    if (uri == null)
                    {
                        throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
                    }

                    entityReferenceLink = new ODataEntityReferenceLink {
                        Url = uri
                    };
                }

                messageWriter.WriteEntityReferenceLink(entityReferenceLink);
            }
        }
        public void CreateODataComplexValue_WritesNestedOpenComplexTypes()
        {
            // Arrange
            IEdmModel model = SerializationTestsHelpers.SimpleOpenTypeModel();

            IEdmComplexType addressType       = model.FindDeclaredType("Default.Address") as IEdmComplexType;
            Type            simpleOpenAddress = typeof(SimpleOpenAddress);

            model.SetAnnotationValue <ClrTypeAnnotation>(addressType, new ClrTypeAnnotation(simpleOpenAddress));
            model.SetAnnotationValue(addressType, new DynamicPropertyDictionaryAnnotation(
                                         simpleOpenAddress.GetProperty("Properties")));

            IEdmComplexType zipCodeType       = model.FindDeclaredType("Default.ZipCode") as IEdmComplexType;
            Type            simpleOpenZipCode = typeof(SimpleOpenZipCode);

            model.SetAnnotationValue <ClrTypeAnnotation>(zipCodeType, new ClrTypeAnnotation(simpleOpenZipCode));
            model.SetAnnotationValue(zipCodeType, new DynamicPropertyDictionaryAnnotation(
                                         simpleOpenZipCode.GetProperty("Properties")));

            IEdmComplexTypeReference addressTypeRef = addressType.ToEdmTypeReference(isNullable: false).AsComplex();

            ODataSerializerProvider    serializerProvider = new DefaultODataSerializerProvider();
            ODataComplexTypeSerializer serializer         = new ODataComplexTypeSerializer(serializerProvider);
            ODataSerializerContext     context            = new ODataSerializerContext
            {
                Model = model
            };

            SimpleOpenAddress topAddress = new SimpleOpenAddress()
            {
                Street     = "TopStreet",
                City       = "TopCity",
                Properties = new Dictionary <string, object>()
                {
                    { "PropertOfAddress", "Value1" }
                }
            };

            SimpleOpenZipCode zipCode = new SimpleOpenZipCode()
            {
                Code       = 101,
                Properties = new Dictionary <string, object>()
                {
                    { "PropertyOfZipCode", "Value2" }
                }
            };

            SimpleOpenAddress subAddress = new SimpleOpenAddress()
            {
                Street     = "SubStreet",
                City       = "SubCity",
                Properties = new Dictionary <string, object>()
                {
                    { "PropertOfSubAddress", "Value3" }
                }
            };

            //  TopAddress (SimpleOpenAddress)
            //       |-- Street                               (declare property, string)
            //       |-- City                                 (declare property, string)
            //       |-- PropertyOfAddress                    (dynamic property, string)
            //       |-- ZipCodeOfAddress                     (dynamic property, SimpleOpenZipCode)
            //              |-- Code                          (declare property, int)
            //              |-- PropertyOfZipCode             (dynamic property, string)
            //              |-- SubAddressOfZipCode           (dynamic property, SimpleOpenAddress)
            //                         |-- Street             (declare property, string)
            //                         |-- City               (declare property, string)
            //                         |-- PropertyOfAddress  (dynamic property, string)
            zipCode.Properties.Add("SubAddressOfZipCode", subAddress);
            topAddress.Properties.Add("ZipCodeOfAddress", zipCode);

            // Act
            var odataValue = serializer.CreateODataComplexValue(topAddress, addressTypeRef, context);

            // Assert
            ODataComplexValue topAddressComplexValue = Assert.IsType <ODataComplexValue>(odataValue);

            Assert.Equal(topAddressComplexValue.TypeName, "Default.Address");
            Assert.Equal(4, topAddressComplexValue.Properties.Count());

            // Verify the dynamic "ZipCodeOfAddress" property, it's nested open complex type
            ODataProperty     dynamicProperty     = Assert.Single(topAddressComplexValue.Properties.Where(p => p.Name == "ZipCodeOfAddress"));
            ODataComplexValue zipCodeComplexValue = Assert.IsType <ODataComplexValue>(dynamicProperty.Value);

            Assert.Equal(zipCodeComplexValue.TypeName, "Default.ZipCode");
            Assert.Equal(3, zipCodeComplexValue.Properties.Count());

            // Verify the declared "Code" property of ZipCode
            ODataProperty code = Assert.Single(zipCodeComplexValue.Properties.Where(p => p.Name == "Code"));

            Assert.Equal(101, code.Value);

            // Verify the dynamic "SubAddressOfZipCode" property of ZipCode
            dynamicProperty = Assert.Single(zipCodeComplexValue.Properties.Where(p => p.Name == "SubAddressOfZipCode"));
            ODataComplexValue subAddressComplexValue = Assert.IsType <ODataComplexValue>(dynamicProperty.Value);

            Assert.Equal(subAddressComplexValue.TypeName, "Default.Address");
            Assert.Equal(3, subAddressComplexValue.Properties.Count());
        }
示例#56
0
        /// <inheritdoc/>
        public override ODataValue CreateODataValue(object graph, IEdmTypeReference expectedType, ODataSerializerContext writeContext)
        {
            if (!expectedType.IsPrimitive())
            {
                throw Error.InvalidOperation(SRResources.CannotWriteType, typeof(ODataPrimitiveSerializer), expectedType.FullName());
            }

            ODataPrimitiveValue value = CreateODataPrimitiveValue(graph, expectedType.AsPrimitive(), writeContext);

            if (value == null)
            {
                return(NullValue);
            }

            return(value);
        }
示例#57
0
        /// <inheritdoc />
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            if (graph == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
            }

            IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;

            if (entitySet == null)
            {
                throw new SerializationException(SRResources.EntitySetMissingDuringSerialization);
            }

            IEdmTypeReference feedType = writeContext.GetEdmType(graph, type);

            Contract.Assert(feedType != null);

            IEdmEntityTypeReference entityType = GetEntityType(feedType);
            ODataDeltaWriter        writer     = messageWriter.CreateODataDeltaWriter(entitySet, entityType.EntityDefinition());

            WriteDeltaFeedInline(graph, feedType, writer, writeContext);
        }