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

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

            ODataCollectionWriter writer = messageWriter.CreateODataCollectionWriter();
            writer.WriteStart(
                new ODataCollectionStart
                {
                    Name = writeContext.ResponseContext.ServiceOperationName
                });

            ODataProperty property = CreateProperty(graph, writeContext.ResponseContext.ServiceOperationName, writeContext);
            if (property != null)
            {
                ODataCollectionValue collectionValue = property.Value as ODataCollectionValue;

                foreach (object item in collectionValue.Items)
                {
                    writer.WriteItem(item);
                }

                writer.WriteEnd();
                writer.Flush();
            }
        }
        public ODataFeedSerializerTests()
        {
            _model       = SerializationTestsHelpers.SimpleCustomerOrderModel();
            _customerSet = _model.FindDeclaredEntityContainer("Default.Container").FindEntitySet("Customers");
            _customers   = new[] {
                new Customer()
                {
                    FirstName = "Foo",
                    LastName  = "Bar",
                    ID        = 10,
                },
                new Customer()
                {
                    FirstName = "Foo",
                    LastName  = "Bar",
                    ID        = 42,
                }
            };

            _customersType = new EdmCollectionTypeReference(
                new EdmCollectionType(
                    new EdmEntityTypeReference(
                        _customerSet.ElementType,
                        isNullable: false)),
                isNullable: false);

            _urlHelper    = new Mock <UrlHelper>(new HttpRequestMessage()).Object;
            _writeContext = new ODataSerializerWriteContext(new ODataResponseContext())
            {
                EntitySet = _customerSet, UrlHelper = _urlHelper
            };
        }
        public ODataFeedSerializerTests()
        {
            _model = SerializationTestsHelpers.SimpleCustomerOrderModel();
            _customerSet = _model.FindDeclaredEntityContainer("Default.Container").FindEntitySet("Customers");
            _customers = new[] {
                new Customer()
                {
                    FirstName = "Foo",
                    LastName = "Bar",
                    ID = 10,
                },
                new Customer()
                {
                    FirstName = "Foo",
                    LastName = "Bar",
                    ID = 42,
                }
            };

            _customersType = new EdmCollectionTypeReference(
                    new EdmCollectionType(
                        new EdmEntityTypeReference(
                            _customerSet.ElementType,
                            isNullable: false)),
                    isNullable: false);

            _urlHelper = new Mock<UrlHelper>(new HttpRequestMessage()).Object;
            _writeContext = new ODataSerializerWriteContext(new ODataResponseContext()) { EntitySet = _customerSet, UrlHelper = _urlHelper };
        }
        private IEnumerable <ODataProperty> CreatePropertyBag(object graph, ODataSerializerWriteContext writeContext)
        {
            IEnumerable <IEdmStructuralProperty> selectProperties;

            if (writeContext.CurrentProjectionNode != null && writeContext.CurrentProjectionNode.Selects.Any())
            {
                selectProperties = _edmEntityTypeReference
                                   .StructuralProperties()
                                   .Where(p => writeContext.CurrentProjectionNode.Selects.Any(node => node.Name == p.Name));
            }
            else
            {
                selectProperties = _edmEntityTypeReference.StructuralProperties();
            }

            List <ODataProperty> properties = new List <ODataProperty>();

            foreach (IEdmStructuralProperty property in selectProperties)
            {
                ODataSerializer serializer = SerializerProvider.GetEdmTypeSerializer(property.Type);
                if (serializer == null)
                {
                    throw Error.NotSupported(SRResources.TypeCannotBeSerialized, property.Type.FullName(), typeof(ODataMediaTypeFormatter).Name);
                }

                object propertyValue = graph.GetType().GetProperty(property.Name).GetValue(graph, index: null);

                properties.Add(serializer.CreateProperty(propertyValue, property.Name, writeContext));
            }

            return(properties);
        }
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            messageWriter.WriteEntityReferenceLink(new ODataEntityReferenceLink { Url = graph as Uri });
        }
        public override ODataProperty CreateProperty(object graph, string elementName, ODataSerializerWriteContext writeContext)
        {
            if (String.IsNullOrWhiteSpace(elementName))
            {
                throw Error.ArgumentNullOrEmpty("elementName");
            }

            // TODO: Bug 467598: validate the type of the object being passed in here with the underlying primitive type. 
            return new ODataProperty() { Value = graph, Name = elementName };
        }
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            ODataWriter writer = messageWriter.CreateODataFeedWriter();
            WriteObjectInline(graph, writer, writeContext);
            writer.Flush();
        }
        private void WriteNavigationLinks(EntityInstanceContext context, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            foreach (IEdmNavigationProperty navProperty in _edmEntityTypeReference.NavigationProperties())
            {
                IEdmTypeReference propertyType  = navProperty.Type;
                object            propertyValue = context.EntityInstance.GetType().GetProperty(navProperty.Name).GetValue(context.EntityInstance, index: null);

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

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

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

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

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

                        serializer.WriteObjectInline(propertyValue, writer, childWriteContext);
                        writer.WriteEnd();
                    }
                    else if (!writeContext.IsRequest)
                    {
                        // delayed links cannot be written on requests
                        writer.WriteStart(navigationLink);
                        writer.WriteEnd();
                    }
                }
            }
        }
        public override ODataProperty CreateProperty(object graph, string elementName, ODataSerializerWriteContext writeContext)
        {
            if (String.IsNullOrWhiteSpace(elementName))
            {
                throw Error.ArgumentNullOrEmpty("elementName");
            }

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

            List<ODataProperty> propertyCollection = null;

            if (graph != null)
            {
                propertyCollection = new List<ODataProperty>();
                foreach (IEdmProperty property in _edmComplexType.ComplexDefinition().Properties())
                {
                    IEdmTypeReference propertyType = property.Type;
                    ODataSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(propertyType);
                    if (propertySerializer == null)
                    {
                        throw Error.NotSupported("Type {0} is not a serializable type", propertyType.FullName());
                    }

                    // TODO 453795: [OData]Cleanup reflection code in the ODataFormatter.
                    object propertyValue = graph.GetType().GetProperty(property.Name).GetValue(graph, index: null);

                    propertyCollection.Add(propertySerializer.CreateProperty(propertyValue, property.Name, writeContext));
                }
            }

            if (propertyCollection != null)
            {
                return new ODataProperty()
                {
                    Name = elementName,
                    Value = new ODataComplexValue()
                    {
                        Properties = propertyCollection,
                        TypeName = _edmComplexType.FullName()
                    }
                };
            }
            else
            {
                return null;
            }
        }
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

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

            ODataProperty property = CreateProperty(graph, writeContext.ResponseContext.ServiceOperationName, writeContext);
            messageWriter.WriteProperty(property);
        }
        public override void WriteObjectInline(object graph, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

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

            if (graph != null)
            {
                WriteFeed(graph, writer, writeContext);
            }
            else
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, ODataFormatterConstants.Feed));
            }
        }
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (graph == null)
            {
                throw Error.ArgumentNull("graph");
            }

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

            ODataError odataError = graph as ODataError;          
            if (odataError == null)
            {
                throw Error.InvalidOperation(SRResources.ErrorTypeMustBeODataError, graph.GetType().FullName);
            }

            bool includeDebugInformation = odataError.InnerError != null;
            messageWriter.WriteError(odataError, includeDebugInformation);
        }
        public override void WriteObjectInline(object graph, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

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

            if (graph != null)
            {
                WriteFeed(graph, writer, writeContext);
            }
            else
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, ODataFormatterConstants.Feed));
            }
        }
        public override void WriteObjectInline(object graph, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

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

            if (graph != null)
            {
                IEnumerable <ODataProperty> propertyBag = CreatePropertyBag(graph, writeContext);
                WriteEntry(graph, propertyBag, writer, writeContext);
            }
            else
            {
                throw new SerializationException(Error.Format(Properties.SRResources.CannotSerializerNull, ODataFormatterConstants.Entry));
            }
        }
        public override void WriteObjectInline(object graph, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

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

            if (graph != null)
            {
                IEnumerable<ODataProperty> propertyBag = CreatePropertyBag(graph, writeContext);
                WriteEntry(graph, propertyBag, writer, writeContext);
            }
            else
            {
                throw new SerializationException(Error.Format(Properties.SRResources.CannotSerializerNull, ODataFormatterConstants.Entry));
            }
        }
        private void WriteEntry(object graph, IEnumerable<ODataProperty> propertyBag, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            IEdmEntityType entityType = _edmEntityTypeReference.EntityDefinition();
            EntityInstanceContext entityInstanceContext = new EntityInstanceContext(SerializerProvider.EdmModel, writeContext.EntitySet, entityType, writeContext.UrlHelper, graph);

            ODataEntry entry = new ODataEntry
            {
                TypeName = _edmEntityTypeReference.FullName(),
                Properties = propertyBag,
            };

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

                string idLink = linkBuilder.BuildIdLink(entityInstanceContext);
                if (idLink != null)
                {
                    entry.Id = idLink;
                }

                Uri readLink = linkBuilder.BuildReadLink(entityInstanceContext);
                if (readLink != null)
                {
                    entry.ReadLink = readLink;
                }

                Uri editLink = linkBuilder.BuildEditLink(entityInstanceContext);
                if (editLink != null)
                {
                    entry.EditLink = editLink;
                }
            }

            writer.WriteStart(entry);
            WriteNavigationLinks(entityInstanceContext, writer, writeContext);
            writer.WriteEnd();
        }
        private void WriteFeed(object graph, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            ODataSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(_edmCollectionType.ElementType());

            if (entrySerializer == null)
            {
                throw Error.NotSupported(SRResources.TypeCannotBeSerialized, _edmCollectionType.ElementType(), typeof(ODataMediaTypeFormatter).Name);
            }

            Contract.Assert(entrySerializer.ODataPayloadKind == ODataPayloadKind.Entry);

            IEnumerable enumerable = graph as IEnumerable; // Data to serialize

            if (enumerable != null)
            {
                ODataFeed feed = new ODataFeed();

                // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ?
                feed.Id = FeedNamespace + _edmCollectionType.FullName();

                // If we have more OData format specific information apply it now.
                ODataResult odataFeedAnnotations = graph as ODataResult;
                if (odataFeedAnnotations != null)
                {
                    feed.Count        = odataFeedAnnotations.Count;
                    feed.NextPageLink = odataFeedAnnotations.NextPageLink;
                }

                writer.WriteStart(feed);

                foreach (object entry in enumerable)
                {
                    entrySerializer.WriteObjectInline(entry, writer, writeContext);
                }

                writer.WriteEnd();
            }
        }
        /// <inheritdoc/>
        public override ODataProperty CreateProperty(object graph, string elementName, ODataSerializerWriteContext writeContext)
        {
            if (String.IsNullOrWhiteSpace(elementName))
            {
                throw Error.ArgumentNullOrEmpty("elementName");
            }

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

            IEnumerable enumerable = graph as IEnumerable;
            if (enumerable != null)
            {
                ArrayList valueCollection = new ArrayList();

                IEdmTypeReference itemType = _edmCollectionType.ElementType();
                ODataSerializer itemSerializer = SerializerProvider.GetEdmTypeSerializer(itemType);
                if (itemSerializer == null)
                {
                    throw Error.NotSupported(SRResources.TypeCannotBeSerialized, itemType.FullName(), typeof(ODataMediaTypeFormatter).Name);
                }

                foreach (object item in enumerable)
                {
                    valueCollection.Add(itemSerializer.CreateProperty(item, ODataFormatterConstants.Element, writeContext).Value);
                }

                // 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.
                // Also, note that TypeName is an optional property for ODataCollectionValue
                return new ODataProperty() { Name = elementName, Value = new ODataCollectionValue { Items = valueCollection } };
            }

            return null;
        }
        private void WriteFeed(object graph, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            ODataSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(_edmCollectionType.ElementType());
            if (entrySerializer == null)
            {
                throw Error.NotSupported(SRResources.TypeCannotBeSerialized, _edmCollectionType.ElementType(), typeof(ODataMediaTypeFormatter).Name);
            }

            Contract.Assert(entrySerializer.ODataPayloadKind == ODataPayloadKind.Entry);

            IEnumerable enumerable = graph as IEnumerable; // Data to serialize
            if (enumerable != null)
            {
                ODataFeed feed = new ODataFeed();

                // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ?
                feed.Id = FeedNamespace + _edmCollectionType.FullName();

                // If we have more OData format specific information apply it now.
                ODataResult odataFeedAnnotations = graph as ODataResult;
                if (odataFeedAnnotations != null)
                {
                    feed.Count = odataFeedAnnotations.Count;
                    feed.NextPageLink = odataFeedAnnotations.NextPageLink;
                }

                writer.WriteStart(feed);

                foreach (object entry in enumerable)
                {
                    entrySerializer.WriteObjectInline(entry, writer, writeContext);
                }

                writer.WriteEnd();
            }
        }
Example #20
0
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (graph == null)
            {
                throw Error.ArgumentNull("graph");
            }

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

            ODataError odataError = graph as ODataError;

            if (odataError == null)
            {
                throw Error.InvalidOperation(SRResources.ErrorTypeMustBeODataError, graph.GetType().FullName);
            }

            bool includeDebugInformation = odataError.InnerError != null;

            messageWriter.WriteError(odataError, includeDebugInformation);
        }
        public override ODataProperty CreateProperty(object graph, string elementName, ODataSerializerWriteContext writeContext)
        {
            if (String.IsNullOrWhiteSpace(elementName))
            {
                throw Error.ArgumentNullOrEmpty("elementName");
            }

            string value = null;

            if (graph != null)
            {
                // TODO: Bug 453831: [OData] Figure out how OData serializes enum flags
                value = graph.ToString();
            }

            ODataProperty property = new ODataProperty()
            {
                Name = elementName,
                Value = value
            };

            return property;
        }
Example #22
0
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            messageWriter.WriteEntityReferenceLink(new ODataEntityReferenceLink {
                Url = graph as Uri
            });
        }
        private void WriteEntry(object graph, IEnumerable <ODataProperty> propertyBag, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            IEdmEntityType        entityType            = _edmEntityTypeReference.EntityDefinition();
            EntityInstanceContext entityInstanceContext = new EntityInstanceContext(SerializerProvider.EdmModel, writeContext.EntitySet, entityType, writeContext.UrlHelper, graph);

            ODataEntry entry = new ODataEntry
            {
                TypeName   = _edmEntityTypeReference.FullName(),
                Properties = propertyBag,
            };

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

                string idLink = linkBuilder.BuildIdLink(entityInstanceContext);
                if (idLink != null)
                {
                    entry.Id = idLink;
                }

                Uri readLink = linkBuilder.BuildReadLink(entityInstanceContext);
                if (readLink != null)
                {
                    entry.ReadLink = readLink;
                }

                Uri editLink = linkBuilder.BuildEditLink(entityInstanceContext);
                if (editLink != null)
                {
                    entry.EditLink = editLink;
                }
            }

            writer.WriteStart(entry);
            WriteNavigationLinks(entityInstanceContext, writer, writeContext);
            writer.WriteEnd();
        }
Example #24
0
        /// <inheritdoc/>
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

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

            ODataCollectionWriter writer = messageWriter.CreateODataCollectionWriter();

            writer.WriteStart(
                new ODataCollectionStart
            {
                Name = writeContext.ResponseContext.ServiceOperationName
            });

            ODataProperty property = CreateProperty(graph, writeContext.ResponseContext.ServiceOperationName, writeContext);

            if (property != null)
            {
                ODataCollectionValue collectionValue = property.Value as ODataCollectionValue;

                foreach (object item in collectionValue.Items)
                {
                    writer.WriteItem(item);
                }

                writer.WriteEnd();
                writer.Flush();
            }
        }
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

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

            ODataWriter writer = messageWriter.CreateODataEntryWriter();

            WriteObjectInline(graph, writer, writeContext);
            writer.Flush();
        }
        public override ODataProperty CreateProperty(object graph, string elementName, ODataSerializerWriteContext writeContext)
        {
            if (String.IsNullOrWhiteSpace(elementName))
            {
                throw Error.ArgumentNullOrEmpty("elementName");
            }

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

            List <ODataProperty> propertyCollection = null;

            if (graph != null)
            {
                propertyCollection = new List <ODataProperty>();
                foreach (IEdmProperty property in _edmComplexType.ComplexDefinition().Properties())
                {
                    IEdmTypeReference propertyType       = property.Type;
                    ODataSerializer   propertySerializer = SerializerProvider.GetEdmTypeSerializer(propertyType);
                    if (propertySerializer == null)
                    {
                        throw Error.NotSupported("Type {0} is not a serializable type", propertyType.FullName());
                    }

                    // TODO 453795: [OData]Cleanup reflection code in the ODataFormatter.
                    object propertyValue = graph.GetType().GetProperty(property.Name).GetValue(graph, index: null);

                    propertyCollection.Add(propertySerializer.CreateProperty(propertyValue, property.Name, writeContext));
                }
            }

            if (propertyCollection != null)
            {
                return(new ODataProperty()
                {
                    Name = elementName,
                    Value = new ODataComplexValue()
                    {
                        Properties = propertyCollection,
                        TypeName = _edmComplexType.FullName()
                    }
                });
            }
            else
            {
                return(null);
            }
        }
Example #27
0
        /// <inheritdoc/>
        public override ODataProperty CreateProperty(object graph, string elementName, ODataSerializerWriteContext writeContext)
        {
            if (String.IsNullOrWhiteSpace(elementName))
            {
                throw Error.ArgumentNullOrEmpty("elementName");
            }

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

            IEnumerable enumerable = graph as IEnumerable;

            if (enumerable != null)
            {
                ArrayList valueCollection = new ArrayList();

                IEdmTypeReference itemType       = _edmCollectionType.ElementType();
                ODataSerializer   itemSerializer = SerializerProvider.GetEdmTypeSerializer(itemType);
                if (itemSerializer == null)
                {
                    throw Error.NotSupported(SRResources.TypeCannotBeSerialized, itemType.FullName(), typeof(ODataMediaTypeFormatter).Name);
                }

                foreach (object item in enumerable)
                {
                    valueCollection.Add(itemSerializer.CreateProperty(item, ODataFormatterConstants.Element, writeContext).Value);
                }

                // 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.
                // Also, note that TypeName is an optional property for ODataCollectionValue
                return(new ODataProperty()
                {
                    Name = elementName, Value = new ODataCollectionValue {
                        Items = valueCollection
                    }
                });
            }

            return(null);
        }
        private void WriteNavigationLinks(EntityInstanceContext context, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            foreach (IEdmNavigationProperty navProperty in _edmEntityTypeReference.NavigationProperties())
            {
                IEdmTypeReference propertyType = navProperty.Type;
                object propertyValue = context.EntityInstance.GetType().GetProperty(navProperty.Name).GetValue(context.EntityInstance, index: null);

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

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

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

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

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

                        serializer.WriteObjectInline(propertyValue, writer, childWriteContext);
                        writer.WriteEnd();
                    }
                    else if (!writeContext.IsRequest)
                    {
                        // delayed links cannot be written on requests
                        writer.WriteStart(navigationLink);
                        writer.WriteEnd();
                    }
                }
            }
        }
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext 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();
        }
        private IEnumerable<ODataProperty> CreatePropertyBag(object graph, ODataSerializerWriteContext writeContext)
        {
            IEnumerable<IEdmStructuralProperty> selectProperties;
            if (writeContext.CurrentProjectionNode != null && writeContext.CurrentProjectionNode.Selects.Any())
            {
                selectProperties = _edmEntityTypeReference
                                    .StructuralProperties()
                                    .Where(p => writeContext.CurrentProjectionNode.Selects.Any(node => node.Name == p.Name));
            }
            else
            {
                selectProperties = _edmEntityTypeReference.StructuralProperties();
            }

            List<ODataProperty> properties = new List<ODataProperty>();

            foreach (IEdmStructuralProperty property in selectProperties)
            {
                ODataSerializer serializer = SerializerProvider.GetEdmTypeSerializer(property.Type);
                if (serializer == null)
                {
                    throw Error.NotSupported(SRResources.TypeCannotBeSerialized, property.Type.FullName(), typeof(ODataMediaTypeFormatter).Name);
                }

                object propertyValue = graph.GetType().GetProperty(property.Name).GetValue(graph, index: null);

                properties.Add(serializer.CreateProperty(propertyValue, property.Name, writeContext));
            }

            return properties;
        }
Example #31
0
 /// <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="writer">The <see cref="ODataWriter" /> to be used for writing</param>
 /// <param name="writeContext">The <see cref="ODataSerializerWriteContext" /></param>
 public virtual void WriteObjectInline(object graph, ODataWriter writer, ODataSerializerWriteContext writeContext)
 {
     throw Error.NotSupported(SRResources.WriteObjectInlineNotSupported, GetType().Name);
 }
Example #32
0
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

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

            messageWriter.WriteProperty(
                CreateProperty(graph, writeContext.ResponseContext.ServiceOperationName, writeContext));
        }
Example #33
0
 /// <summary>
 /// Create a <see cref="ODataProperty" /> that gets written as a part of an <see cref="ODataItem" /> with the given propertyName
 /// and the writeContext.
 /// </summary>
 /// <param name="graph">The object to be written </param>
 /// <param name="elementName">The name of the property to create</param>
 /// <param name="writeContext">The <see cref="ODataSerializerWriteContext" /></param>
 /// <returns>The <see cref="ODataProperty" /> created.</returns>
 public virtual ODataProperty CreateProperty(object graph, string elementName, ODataSerializerWriteContext writeContext)
 {
     throw Error.NotSupported(SRResources.CreatePropertyNotSupported, GetType().Name);
 }
 /// <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="writer">The <see cref="ODataWriter" /> to be used for writing</param>
 /// <param name="writeContext">The <see cref="ODataSerializerWriteContext" /></param>
 public virtual void WriteObjectInline(object graph, ODataWriter writer, ODataSerializerWriteContext writeContext)
 {
     throw Error.NotSupported(SRResources.WriteObjectInlineNotSupported, GetType().Name);
 }
Example #35
0
        public override ODataProperty CreateProperty(object graph, string elementName, ODataSerializerWriteContext writeContext)
        {
            if (String.IsNullOrWhiteSpace(elementName))
            {
                throw Error.ArgumentNullOrEmpty("elementName");
            }

            // TODO: Bug 467598: validate the type of the object being passed in here with the underlying primitive type.
            return(new ODataProperty()
            {
                Value = graph, Name = elementName
            });
        }
 /// <summary>
 /// Create a <see cref="ODataProperty" /> that gets written as a part of an <see cref="ODataItem" /> with the given propertyName 
 /// and the writeContext.
 /// </summary>
 /// <param name="graph">The object to be written </param>
 /// <param name="elementName">The name of the property to create</param>
 /// <param name="writeContext">The <see cref="ODataSerializerWriteContext" /></param>
 /// <returns>The <see cref="ODataProperty" /> created.</returns>
 public virtual ODataProperty CreateProperty(object graph, string elementName, ODataSerializerWriteContext writeContext)
 {
     throw Error.NotSupported(SRResources.CreatePropertyNotSupported, GetType().Name);
 }
Example #37
0
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerWriteContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            messageWriter.WriteServiceDocument(graph as ODataWorkspace);
        }
        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

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

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;
            return TaskHelpers.RunSynchronously(() =>
            {
                // Get the format and version to use from the ODataServiceVersion content header or if not available use the
                // values configured for the specialized formatter instance.
                ODataVersion version;
                ODataFormat odataFormat;
                if (contentHeaders == null)
                {
                    version = _defaultODataVersion;
                    odataFormat = ODataFormatterConstants.DefaultODataFormat;
                }
                else
                {
                    version = GetODataVersion(contentHeaders, ODataFormatterConstants.ODataServiceVersion) ?? _defaultODataVersion;
                    odataFormat = GetODataFormat(contentHeaders);
                }

                ODataSerializer serializer = ODataSerializerProvider.GetODataPayloadSerializer(type);
                if (serializer == null)
                {
                    throw Error.InvalidOperation(SRResources.TypeCannotBeSerialized, type.Name, typeof(ODataMediaTypeFormatter).Name);
                }

                if (IsClient)
                {
                    // TODO: Bug 467617: figure out the story for the operation name on the client side and server side.
                    string operationName = (value != null ? value.GetType() : type).Name;

                    // serialize a request
                    IODataRequestMessage requestMessage = new ODataMessageWrapper(writeStream);
                    ODataResponseContext responseContext = new ODataResponseContext(requestMessage, odataFormat, version, new Uri(ODataFormatterConstants.DefaultNamespace), operationName);

                    ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                    {
                        BaseUri = responseContext.BaseAddress,
                        Version = responseContext.ODataVersion,
                        Indent = responseContext.IsIndented,
                        DisableMessageStreamDisposal = true,
                    };

                    writerSettings.SetContentType(responseContext.ODataFormat);
                    using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage, writerSettings, Model))
                    {
                        ODataSerializerWriteContext writeContext = new ODataSerializerWriteContext(responseContext);
                        serializer.WriteObject(value, messageWriter, writeContext);
                    }
                }
                else
                {
                    UrlHelper urlHelper = Request.GetUrlHelper();
                    NameValueCollection queryStringValues = Request.RequestUri.ParseQueryString();

                    IEdmEntitySet targetEntitySet = null;
                    ODataUriHelpers.TryGetEntitySetAndEntityType(Request.RequestUri, Model, out targetEntitySet);

                    ODataQueryProjectionNode rootProjectionNode = null;
                    if (targetEntitySet != null)
                    {
                        // TODO: Bug 467621: Move to ODataUriParser once it is done.
                        rootProjectionNode = ODataUriHelpers.GetODataQueryProjectionNode(queryStringValues["$select"], queryStringValues["$expand"], targetEntitySet);
                    }

                    // serialize a response
                    Uri baseAddress = new Uri(Request.RequestUri, Request.GetConfiguration().VirtualPathRoot);

                    // TODO: Bug 467617: figure out the story for the operation name on the client side and server side.
                    // This is clearly a workaround. We are assuming that the operation name is the last segment in the request uri 
                    // which works for most cases and fall back to the type name of the object being written.
                    // We should rather use uri parser semantic tree to figure out the operation name from the request url.
                    string operationName = ODataUriHelpers.GetOperationName(Request.RequestUri, baseAddress);
                    operationName = operationName ?? type.Name;

                    IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream);
                    ODataResponseContext responseContext = new ODataResponseContext(responseMessage, odataFormat, version, baseAddress, operationName);

                    ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                    {
                        BaseUri = responseContext.BaseAddress,
                        Version = responseContext.ODataVersion,
                        Indent = responseContext.IsIndented,
                        DisableMessageStreamDisposal = true,
                    };
                    if (contentHeaders != null && contentHeaders.ContentType != null)
                    {
                        writerSettings.SetContentType(contentHeaders.ContentType.ToString(), Encoding.UTF8.WebName);
                    }

                    using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, ODataDeserializerProvider.EdmModel))
                    {
                        ODataSerializerWriteContext writeContext = new ODataSerializerWriteContext(responseContext)
                                                                       {
                                                                           EntitySet = targetEntitySet,
                                                                           UrlHelper = urlHelper,
                                                                           RootProjectionNode = rootProjectionNode,
                                                                           CurrentProjectionNode = rootProjectionNode
                                                                       };

                        serializer.WriteObject(value, messageWriter, writeContext);
                    }
                }
            });
        }