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

            entry.ETag = Utility.GetETagValue(element);

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

                entry = selectItemHandler.ProjectedEntry;
            }

            CustomizeEntry(incomingHeaders, entry);

            writer.WriteStart(entry);

            // gets all of the expandedItems, including ExpandedRefernceSelectItem and ExpandedNavigationItem
            var expandedItems = selectExpandClause == null ? null : selectExpandClause.SelectedItems.OfType<ExpandedReferenceSelectItem>();
            WriteNavigationLinks(writer, element, entry.ReadLink, entitySource, targetVersion, expandedItems);
            writer.WriteEnd();
        }
 private void StartRead(ODataReader reader, ODataWriter writer)
 {
     ExceptionUtilities.Assert(reader.State == ODataReaderState.Start, "Reader is expected to be in state Start at StartRead.");
     while (reader.Read())
     {
         switch(reader.State)
         {
             case ODataReaderState.EntryStart:
                 writer.WriteStart((ODataEntry)reader.Item);
                 break;
             case ODataReaderState.FeedStart:
                 writer.WriteStart((ODataFeed)reader.Item);
                 break;
             case ODataReaderState.NavigationLinkStart:
                 writer.WriteStart((ODataNavigationLink)reader.Item);
                 break;
             case ODataReaderState.EntryEnd:
             case ODataReaderState.FeedEnd:
             case ODataReaderState.NavigationLinkEnd:
                 writer.WriteEnd();
                 break;
             default:
                 throw new NotSupportedException();
         };
     }
 }
Example #3
0
        /// <summary>
        /// Writes an OData entry.
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the entry.</param>
        /// <param name="element">The item from the data store to write.</param>
        /// <param name="entitySet">The entity set in the model that the entry belongs to.</param>
        /// <param name="model">The data store model.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <param name="expandedNavigationProperties">A list of navigation property names to expand.</param>
        public static void WriteEntry(ODataWriter writer, object element, IEdmEntitySet entitySet, IEdmModel model, ODataVersion targetVersion, IEnumerable<string> expandedNavigationProperties) 
        {
            var entry = ODataObjectModelConverter.ConvertToODataEntry(element, entitySet, targetVersion);

            writer.WriteStart(entry);

            // Here, we write out the links for the navigation properties off of the entity type
            WriteNavigationLinks(writer, element, entry.ReadLink, entitySet.EntityType(), model, targetVersion, expandedNavigationProperties);

            writer.WriteEnd();
        }
Example #4
0
        /// <summary>
        /// Writes an OData feed.
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the feed.</param>
        /// <param name="entries">The items from the data store to write to the feed.</param>
        /// <param name="entitySet">The entity set in the model that the feed belongs to.</param>
        /// <param name="model">The data store model.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <param name="expandedNavigationProperties">A list of navigation property names to expand.</param>
        public static void WriteFeed(ODataWriter writer, IEnumerable entries, IEdmEntitySet entitySet, IEdmModel model, ODataVersion targetVersion, IEnumerable<string> expandedNavigationProperties)
        {
            var feed = new ODataFeed {Id = new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name)};
            writer.WriteStart(feed);

            foreach (var element in entries)
            {
                WriteEntry(writer, element, entitySet, model, targetVersion, expandedNavigationProperties);
            }

            writer.WriteEnd();
        }
        private void WriteExpandedNavigationProperty(
            KeyValuePair<IEdmNavigationProperty, SelectExpandClause> navigationPropertyToExpand,
            EntityInstanceContext entityInstanceContext,
            ODataWriter writer)
        {
            Contract.Assert(entityInstanceContext != null);
            Contract.Assert(writer != null);

            IEdmNavigationProperty navigationProperty = navigationPropertyToExpand.Key;
            SelectExpandClause selectExpandClause = navigationPropertyToExpand.Value;

            object propertyValue = entityInstanceContext.GetPropertyValue(navigationProperty.Name);

            if (propertyValue == null)
            {
                if (navigationProperty.Type.IsCollection())
                {
                    // A navigation property whose Type attribute specifies a collection, the collection always exists,
                    // it may just be empty.
                    // If a collection of entities can be related, it is represented as a JSON array. An empty
                    // collection of entities (one that contains no entities) is represented as an empty JSON array.
                    writer.WriteStart(new ODataFeed());
                }
                else
                {
                    // If at most one entity can be related, the value is null if no entity is currently related.
                    writer.WriteStart(entry: null);
                }

                writer.WriteEnd();
            }
            else
            {
                // create the serializer context for the expanded item.
                ODataSerializerContext nestedWriteContext = new ODataSerializerContext(entityInstanceContext, selectExpandClause, navigationProperty);

                // write object.
                ODataEdmTypeSerializer serializer = SerializerProvider.GetEdmTypeSerializer(navigationProperty.Type);
                if (serializer == null)
                {
                    throw new SerializationException(
                        Error.Format(SRResources.TypeCannotBeSerialized, navigationProperty.Type.ToTraceString(), typeof(ODataMediaTypeFormatter).Name));
                }

                serializer.WriteObjectInline(propertyValue, navigationProperty.Type, writer, nestedWriteContext);
            }
        }
        private void WriteNavigationLinks(
            IEnumerable<IEdmNavigationProperty> navigationProperties, EntityInstanceContext entityInstanceContext, ODataWriter writer)
        {
            Contract.Assert(entityInstanceContext != null);

            IEnumerable<ODataNavigationLink> navigationLinks = CreateNavigationLinks(navigationProperties, entityInstanceContext);
            foreach (ODataNavigationLink navigationLink in navigationLinks)
            {
                writer.WriteStart(navigationLink);
                writer.WriteEnd();
            }
        }
        private void WriteEntry(object graph, ODataWriter writer, ODataSerializerContext writeContext,
            IEdmTypeReference expectedType)
        {
            Contract.Assert(writeContext != null);

            if (EdmLibHelpers.IsDynamicTypeWrapper(graph.GetType()))
            {
                WriteDynamicTypeEntry(graph, writer, expectedType, writeContext);
                return;
            }

            IEdmEntityTypeReference entityType = GetEntityType(graph, writeContext);
            EntityInstanceContext entityInstanceContext = new EntityInstanceContext(writeContext, entityType, graph);

            SelectExpandNode selectExpandNode = CreateSelectExpandNode(entityInstanceContext);
            if (selectExpandNode != null)
            {
                ODataEntry entry = CreateEntry(selectExpandNode, entityInstanceContext);
                if (entry != null)
                {
                    writer.WriteStart(entry);
                    WriteNavigationLinks(selectExpandNode.SelectedNavigationProperties, entityInstanceContext, writer);
                    WriteExpandedNavigationProperties(selectExpandNode.ExpandedNavigationProperties,
                        entityInstanceContext, writer);
                    writer.WriteEnd();
                }
            }
        }
Example #8
0
        private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer,
            ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(feedType != null);

            IEdmEntityTypeReference elementType = GetEntityType(feedType);
            ODataFeed feed = CreateODataFeed(enumerable, feedType.AsCollection(), writeContext);
            if (feed == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, Feed));
            }

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

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

            writer.WriteStart(feed);

            foreach (object entry in enumerable)
            {
                if (entry == null)
                {
                    throw new SerializationException(SRResources.NullElementInCollection);
                }

                entrySerializer.WriteObjectInline(entry, elementType, writer, writeContext);
            }

            // Subtle and suprising 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)
            {
                feed.NextPageLink = nextPageLink;
            }

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

                writer.WriteEnd();
            }
        }
        private void WriteNavigationLink(ODataWriter writer, ODataNavigationLink link)
        {
            writer.WriteStart(link);
            var expanded = link.GetAnnotation<ODataNavigationLinkExpandedItemObjectModelAnnotation>();
            if (expanded != null)
            {
                var feed = expanded.ExpandedItem as ODataFeed;
                if (feed != null)
                {
                    this.WriteFeed(writer, feed);
                }
                else
                {
                    ODataEntry entry = expanded.ExpandedItem as ODataEntry;
                    if (entry != null || expanded.ExpandedItem == null)
                    {
                        this.WriteEntry(writer, entry);
                    }
                    else
                    {
                        ExceptionUtilities.Assert(expanded.ExpandedItem is ODataEntityReferenceLink, "Content of a nav. link can only be a feed, entry or entity reference link.");
                        writer.WriteEntityReferenceLink((ODataEntityReferenceLink)expanded.ExpandedItem);
                    }
                }
            }

            writer.WriteEnd();
        }
        private void WriteEntry(ODataWriter writer, ODataEntry entry)
        {
            writer.WriteStart(entry);
            var annotation = entry.GetAnnotation<ODataEntryNavigationLinksObjectModelAnnotation>();
            ODataNavigationLink navLink = null;
            if (annotation != null)
            {
                for (int i = 0; i < annotation.Count; ++i)
                {
                    bool found = annotation.TryGetNavigationLinkAt(i, out navLink);
                    ExceptionUtilities.Assert(found, "Navigation links should be ordered sequentially for writing");
                    this.WriteNavigationLink(writer, navLink);
                }
            }

            writer.WriteEnd();
        }
        private void WriteFeed(ODataWriter writer, ODataFeed feed)
        {
            writer.WriteStart(feed);
            var annotation = feed.GetAnnotation<ODataFeedEntriesObjectModelAnnotation>();
            if (annotation != null)
            {
                foreach (var entry in annotation)
                {
                    this.WriteEntry(writer, entry);
                }
            }

            writer.WriteEnd();
        }
        /// <summary>
        /// Writes an OData feed.
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the feed.</param>
        /// <param name="entityType">The type of the entity in the feed.</param>
        /// <param name="entries">The items from the data store to write to the feed.</param>
        /// <param name="entitySet">The entity set in the model that the feed belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <param name="selectExpandClause">The SelectExpandClause.</param>
        public static void WriteFeed(ODataWriter writer, IEdmEntityType entityType, IEnumerable entries, IEdmEntitySetBase entitySet, ODataVersion targetVersion, SelectExpandClause selectExpandClause, long? count, Uri deltaLink, Uri nextPageLink, Dictionary<string, string> incomingHeaders = null)
        {
            var feed = new ODataFeed
            {
                Id = entitySet == null ? null : new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name),
                DeltaLink = deltaLink,
                NextPageLink = nextPageLink
            };

            if (entitySet == null)
            {
                feed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo()
                {
                    NavigationSourceEntityTypeName = entityType.FullTypeName(),
                    NavigationSourceName = null,
                    NavigationSourceKind = EdmNavigationSourceKind.UnknownEntitySet,
                    IsFromCollection = true
                });
            }

            if (count.HasValue)
            {
                feed.Count = count;
            }

            writer.WriteStart(feed);

            foreach (var element in entries)
            {
                WriteEntry(writer, element, entitySet, targetVersion, selectExpandClause, incomingHeaders);
            }

            writer.WriteEnd();
        }
		private async Task WriteNodeAsync(ODataWriter writer, ODataEntry entry, SelectExpandNode selectExpandNode,
			EntityInstanceContext entityInstanceContext)
		{

			//(entityInstanceContext.EdmModel as ISelectExpandWrapper<string>)
			writer.WriteStart(entry);
			await WriteNavigationLinksAsync(selectExpandNode.SelectedNavigationProperties, entityInstanceContext, writer);
			await WriteExpandedNavigationPropertiesAsync(selectExpandNode.ExpandedNavigationProperties, entityInstanceContext, writer);
			writer.WriteEnd();
		}
Example #15
0
        private static void WriteNavigationLinks(ODataWriter writer, object element, Uri parentEntryUri, IEdmEntityType parentEntityType, IEdmModel model, ODataVersion targetVersion, IEnumerable<string> expandedNavigationProperties) 
        {
            foreach (var navigationProperty in parentEntityType.NavigationProperties())
            {
                IEdmTypeReference propertyTypeReference = navigationProperty.Type;
                bool isCollection = navigationProperty.Type.IsCollection();

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

                writer.WriteStart(navigationLink);

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

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

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

                writer.WriteEnd();
            }
            
        }
Example #16
0
 /// <summary>
 /// Writes a ReferenceLink
 /// </summary>
 /// <param name="writer">The ODataWriter that will write the ReferenceLink.</param>
 public static void WriteReferenceLink(ODataWriter writer, object element, IEdmNavigationSource entitySource, ODataVersion targetVersion, ODataNavigationLink navigationLink)
 {
     ODataEntry entry = ODataObjectModelConverter.ConvertToODataEntityReferenceLink (element, entitySource, targetVersion);
     writer.WriteStart(entry);
     writer.WriteEnd();
 }
Example #17
0
 /// <summary>
 /// Writes a ReferenceLinks
 /// </summary>
 /// <param name="writer">The ODataWriter that will write the ReferenceLinks.</param>
 public static void WriteReferenceLinks(ODataWriter writer, IEnumerable element, IEdmNavigationSource entitySource, ODataVersion targetVersion, ODataNavigationLink navigationLink)
 {
     IEnumerable<ODataEntry> links = ODataObjectModelConverter.ConvertToODataEntityReferenceLinks (element, entitySource, targetVersion);
     var feed = new ODataFeed { };
     writer.WriteStart(feed);
     foreach (var entry in links)
     {
         writer.WriteStart(entry);
         writer.WriteEnd();
     }
     writer.WriteEnd();
 }
Example #18
0
 private void InvokeWriterAction(ODataMessageWriterTestWrapper messageWriter, ODataWriter writer, WriterAction writerAction)
 {
     switch (writerAction)
     {
         case WriterAction.StartEntry:
             writer.WriteStart(ObjectModelUtils.CreateDefaultEntry());
             break;
         case WriterAction.StartFeed:
             writer.WriteStart(ObjectModelUtils.CreateDefaultFeed());
             break;
         case WriterAction.StartLink:
             writer.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink());
             break;
         case WriterAction.End:
             writer.WriteEnd();
             break;
         case WriterAction.Error:
             messageWriter.WriteError(new ODataError(), false);
             break;
     }
 }
        private void WriteFeed(ODataWriter writer, ODataItem[] itemsToWrite, ref int currentIdx)
        {
            if (currentIdx < itemsToWrite.Length)
            {
                ODataFeed feed = (ODataFeed)itemsToWrite[currentIdx++];
                writer.WriteStart(feed);
                while (currentIdx < itemsToWrite.Length && itemsToWrite[currentIdx] is ODataEntry)
                {
                    this.WriteEntry(writer, itemsToWrite, ref currentIdx);
                }

                writer.WriteEnd();
            }
        }
Example #20
0
 /// <summary>
 /// Writes a ReferenceLink
 /// </summary>
 /// <param name="writer">The ODataWriter that will write the ReferenceLink.</param>
 public static void WriteReferenceLink(ODataWriter writer, object element, IEdmNavigationSource entitySource, ODataVersion targetVersion, ODataNavigationLink navigationLink)
 {
     ODataEntry entry = ODataObjectModelConverter.ConvertToODataEntityReferenceLink (element, entitySource, targetVersion);
     entry.InstanceAnnotations.Add(new ODataInstanceAnnotation("Link.AnnotationByEntry", new ODataPrimitiveValue(true)));
     writer.WriteStart(entry);
     writer.WriteEnd();
 }
        private void WriteLink(ODataWriter writer, ODataItem[] itemsToWrite, ref int currentIdx)
        {
            if (currentIdx < itemsToWrite.Length)
            {
                ODataNavigationLink link = (ODataNavigationLink)itemsToWrite[currentIdx++];
                writer.WriteStart(link);
                if (currentIdx < itemsToWrite.Length)
                {
                    if (itemsToWrite[currentIdx] is ODataEntry)
                    {
                        this.WriteEntry(writer, itemsToWrite, ref currentIdx);
                    }
                    else if (itemsToWrite[currentIdx] is ODataFeed)
                    {
                        this.WriteFeed(writer, itemsToWrite, ref currentIdx);
                    }
                }

                writer.WriteEnd();
            }
        }
Example #22
0
 /// <summary>
 /// Writes a ReferenceLinks
 /// </summary>
 /// <param name="writer">The ODataWriter that will write the ReferenceLinks.</param>
 public static void WriteReferenceLinks(ODataWriter writer, IEnumerable element, IEdmNavigationSource entitySource, ODataVersion targetVersion, ODataNavigationLink navigationLink)
 {
     IEnumerable<ODataEntry> links = ODataObjectModelConverter.ConvertToODataEntityReferenceLinks (element, entitySource, targetVersion);
     var feed = new ODataFeed { };
     feed.InstanceAnnotations.Add(new ODataInstanceAnnotation("Links.AnnotationByFeed", new ODataPrimitiveValue(true)));
     writer.WriteStart(feed);
     foreach (var entry in links)
     {
         entry.InstanceAnnotations.Add(new ODataInstanceAnnotation("Link.AnnotationInLinks", new ODataPrimitiveValue(true)));
         writer.WriteStart(entry);
         writer.WriteEnd();
     }
     writer.WriteEnd();
 }
        private void WriteDynamicTypeEntry(object graph, ODataWriter writer, IEdmTypeReference expectedType,
            ODataSerializerContext writeContext)
        {
            var navigationProperties = new Dictionary<IEdmTypeReference, object>();
            var entityType = expectedType.Definition as EdmEntityType;
            var entry = new ODataEntry()
            {
                TypeName = expectedType.FullName(),
                Properties = CreateODataPropertiesFromDynamicType(entityType, graph, navigationProperties)
            };

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

            writer.WriteEnd();
        }
 private void WriteEnd(ODataWriter writer, ODataReaderState expectedState)
 {
     this.expectedStates.Add(expectedState);
     writer.WriteEnd();
     writer.Flush();
 }
        private void WriteEntry(object graph, ODataWriter writer, ODataSerializerContext writeContext)
        {
            Contract.Assert(writeContext != null);

            IEdmEntityTypeReference entityType = GetEntityType(graph, writeContext);
            EntityInstanceContext entityInstanceContext = new EntityInstanceContext(writeContext, entityType, graph);
            SelectExpandNode selectExpandNode = CreateSelectExpandNode(entityInstanceContext);
            if (selectExpandNode != null)
            {
                ODataEntry entry = CreateEntry(selectExpandNode, entityInstanceContext);
                if (entry != null)
                {
                    writer.WriteStart(entry);
                    WriteNavigationLinks(selectExpandNode.SelectedNavigationProperties, entityInstanceContext, writer);
                    WriteExpandedNavigationProperties(selectExpandNode.ExpandedNavigationProperties, entityInstanceContext, writer);
                    writer.WriteEnd();
                }
            }
        }
Example #26
0
        /// <summary>
        /// Writes an OData feed.
        /// </summary>
        /// <param name="writer">The ODataWriter that will write the feed.</param>
        /// <param name="entries">The items from the data store to write to the feed.</param>
        /// <param name="entitySet">The entity set in the model that the feed belongs to.</param>
        /// <param name="targetVersion">The OData version this segment is targeting.</param>
        /// <param name="selectExpandClause">The SelectExpandClause.</param>
        public static void WriteFeed(ODataWriter writer, IEnumerable entries, IEdmEntitySetBase entitySet, ODataVersion targetVersion, SelectExpandClause selectExpandClause, long? count, Uri deltaLink, Uri nextPageLink, Dictionary<string, string> incomingHeaders = null)
        {
            var feed = new ODataFeed
            {
                Id = new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name),
                DeltaLink = deltaLink,
                NextPageLink = nextPageLink
            };

            if (count.HasValue)
            {
                feed.Count = count;
            }

            writer.WriteStart(feed);

            foreach (var element in entries)
            {
                WriteEntry(writer, element, entitySet, targetVersion, selectExpandClause, incomingHeaders);
            }

            writer.WriteEnd();
        }
        private void WriteExpandedNavigationProperties(
            IDictionary<IEdmNavigationProperty, SelectExpandClause> navigationPropertiesToExpand,
            EntityInstanceContext entityInstanceContext,
            ODataWriter writer)
        {
            Contract.Assert(navigationPropertiesToExpand != null);
            Contract.Assert(entityInstanceContext != null);
            Contract.Assert(writer != null);

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

                ODataNavigationLink navigationLink = CreateNavigationLink(navigationProperty, entityInstanceContext);
                if (navigationLink != null)
                {
                    writer.WriteStart(navigationLink);
                    WriteExpandedNavigationProperty(navigationPropertyToExpand, entityInstanceContext, writer);
                    writer.WriteEnd();
                }
            }
        }
Example #28
0
        private static void WriteNavigationLinks(ODataWriter writer, object element, Uri parentEntryUri, IEdmNavigationSource edmParent, ODataVersion targetVersion, IEnumerable<SelectItem> expandedItems)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, element)).NavigationProperties())
            {
                // give proprity to ExpandedReferenceSelectItem
                var expandedItem = GetExpandedReferenceItem(expandedItems, navigationProperty.Name);
                if (expandedItem == null)
                {
                    expandedItem = GetExpandedNavigationItem(expandedItems, navigationProperty.Name);
                }

                // For Atom, we always manually write out the links for the navigation properties off of the entity type
                // Or if the navigation is expanded, we manually write out the links for the navigation properties along with the expanded entries
                if (writer.GetType().Name != "ODataJsonLightWriter" || expandedItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    var navigationLink = new ODataNavigationLink
                    {
                        IsCollection = isCollection,
                        Name = navigationProperty.Name,
                    };

                    if (writer.GetType().Name == "ODataAtomWriter")
                    {
                        //If the passed in parentEntryUri is null then exception will be thrown, to avoid this, create a relative 'potato' Uri.
                        navigationLink.Url = (parentEntryUri == null) ? new Uri("potato", UriKind.Relative) : new Uri(new Uri(parentEntryUri.AbsoluteUri + "/"), navigationProperty.Name);
                    }

                    writer.WriteStart(navigationLink);
                    if (expandedItem != null)
                    {
                        ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(element);
                        expandedItem.HandleWith(expandItemHandler);

                        var propertyValue = expandItemHandler.ExpandedChildElement;

                        if (propertyValue != null)
                        {
                            IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                            if (isCollection)
                            {
                                long? count = null;
                                var collectionValue = propertyValue as IEnumerable;
                                if (collectionValue != null && expandedItem.CountOption == true)
                                {
                                    count = collectionValue.Cast<object>().LongCount();
                                }

                                if (expandedItem.GetType() == typeof(ExpandedReferenceSelectItem))
                                {
                                    WriteReferenceLinks(writer, collectionValue, targetSource as IEdmEntitySetBase, targetVersion, navigationLink);
                                }
                                else
                                {
                                    
                                    WriteFeed(writer, collectionValue, targetSource as IEdmEntitySetBase, targetVersion, ((ExpandedNavigationSelectItem)expandedItem).SelectAndExpand, count, null, null);
                                }
                            }
                            else
                            {
                                if (expandedItem.GetType() == typeof(ExpandedReferenceSelectItem))
                                {
                                    WriteReferenceLink(writer, propertyValue, targetSource, targetVersion, navigationLink);
                                }
                                else
                                {
                                    WriteEntry(writer, propertyValue, targetSource, targetVersion, ((ExpandedNavigationSelectItem)expandedItem).SelectAndExpand);                                   
                                }
                            }
                        }
                    }
                    writer.WriteEnd();
                }
            }
        }
        private static void WriteEntry(ODataWriter writer, object entity, IEnumerable<string> projectedProperties)
        {
            var entry = new ODataEntry()
            {
                Id = new Uri("http://temp.org/" + Guid.NewGuid()),
                SerializationInfo = MySerializationInfo
            };

            if (projectedProperties != null)
            {
                entry.SetAnnotation<ProjectedPropertiesAnnotation>(new ProjectedPropertiesAnnotation(projectedProperties));
            }
            
            entry.Properties = entity.GetType().GetProperties().Select(p => new ODataProperty() { Name = p.Name, Value = p.GetValue(entity, null) });

            writer.WriteStart(entry);
            writer.WriteEnd();
        }
        private string WriteAndVerifyRequestMessage(StreamRequestMessage requestMessageWithoutModel,
                                                    ODataWriter odataWriter, bool hasModel, string mimeType)
        {
            var order = new ODataEntry()
                {
                    Id = new Uri(this.ServiceUri + "Order(-10)"),
                    TypeName = NameSpace + "Order"
                };

            var orderP1 = new ODataProperty { Name = "OrderId", Value = -10 };
            var orderp2 = new ODataProperty { Name = "CustomerId", Value = 8212 };
            var orderp3 = new ODataProperty { Name = "Concurrency", Value = null };
            order.Properties = new[] { orderP1, orderp2, orderp3 };
            if (!hasModel)
            {
                order.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo() { NavigationSourceName = "Order", NavigationSourceEntityTypeName = NameSpace + "Order" });
                orderP1.SetSerializationInfo(new ODataPropertySerializationInfo() { PropertyKind = ODataPropertyKind.Key });
            }

            odataWriter.WriteStart(order);
            odataWriter.WriteEnd();

            Stream stream = requestMessageWithoutModel.GetStream();
            if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
            {
                stream.Seek(0, SeekOrigin.Begin);
                var settings = new ODataMessageReaderSettings() { BaseUri = this.ServiceUri };
                ODataMessageReader messageReader = new ODataMessageReader(requestMessageWithoutModel, settings,
                                                                          WritePayloadHelper.Model);
                ODataReader reader = messageReader.CreateODataEntryReader(WritePayloadHelper.OrderSet, WritePayloadHelper.OrderType);
                bool verifyEntryCalled = false;
                while (reader.Read())
                {
                    if (reader.State == ODataReaderState.EntryEnd)
                    {
                        ODataEntry entry = reader.Item as ODataEntry;
                        Assert.IsTrue(entry.Id.ToString().Contains("Order(-10)"), "entry.Id");
                        Assert.AreEqual(3, entry.Properties.Count(), "entry.Properties.Count");
                        verifyEntryCalled = true;
                    }
                }

                Assert.AreEqual(ODataReaderState.Completed, reader.State);
                Assert.IsTrue(verifyEntryCalled, "verifyEntryCalled");
            }

            return WritePayloadHelper.ReadStreamContent(stream);
        }