/// <summary> /// Creates a function that takes in an object and generates nextlink uri. /// </summary> /// <param name="resourceSet">The resource set describing a collection of structured objects.</param> /// <param name="resourceSetInstance">The instance representing the resourceSet being written.</param> /// <param name="writeContext">The serializer context.</param> /// <returns>The function that generates the NextLink from an object.</returns> internal static Func <object, Uri> GetNextLinkGenerator(ODataResourceSetBase resourceSet, IEnumerable resourceSetInstance, ODataSerializerContext writeContext) { if (resourceSet != null && resourceSet.NextPageLink != null) { Uri defaultUri = resourceSet.NextPageLink; return((obj) => { return defaultUri; }); } if (writeContext.ExpandedResource == null) { if (writeContext.Request != null && writeContext.QueryContext != null) { SkipTokenHandler handler = writeContext.QueryContext.GetSkipTokenHandler(); return((obj) => { return handler.GenerateNextPageLink(new System.Uri(writeContext.Request.GetEncodedUrl()), (writeContext.Request.ODataFeature() as ODataFeature).PageSize, obj, writeContext); }); } } else { // nested resourceSet ITruncatedCollection truncatedCollection = resourceSetInstance as ITruncatedCollection; if (truncatedCollection != null && truncatedCollection.IsTruncated) { return((obj) => { return GetNestedNextPageLink(writeContext, truncatedCollection.PageSize, obj); }); } } return((obj) => { return null; }); }
/// <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.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); } ICountOptionCollection countOptionCollection = feedInstance as ICountOptionCollection; if (countOptionCollection != null && countOptionCollection.TotalCount != null) { feed.Count = countOptionCollection.TotalCount; } } return(feed); }
/// <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, Context = writeContext.Context, 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.Context.ODataFeature().NextLink; long?countValue = writeContext.Context.ODataFeature().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); }
/// <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 } }); } } // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ? feed.Id = "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.GetNextPageLink(); long?inlineCount = writeContext.Request.GetInlineCount(); if (inlineCount.HasValue) { feed.Count = inlineCount.Value; } } } else { // nested feed ITruncatedCollection truncatedCollection = feedInstance as ITruncatedCollection; if (truncatedCollection != null && truncatedCollection.IsTruncated) { feed.NextPageLink = GetNestedNextPageLink(writeContext, truncatedCollection.PageSize); } } return(feed); }
/// <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.NavigationSource != null) { FeedContext feedContext = new FeedContext { Request = writeContext.Request, RequestContext = writeContext.RequestContext, EntitySetBase = writeContext.NavigationSource as IEdmEntitySetBase, Url = writeContext.Url, FeedInstance = feedInstance }; IEdmEntityType entityType = GetEntityType(feedType).Definition as IEdmEntityType; var operations = writeContext.Model.GetAvailableOperationsBoundToCollection(entityType); var odataOperations = CreateODataOperations(operations, feedContext, writeContext); foreach (var odataOperation in odataOperations) { ODataAction action = odataOperation as ODataAction; if (action != null) { feed.AddAction(action); } else { feed.AddFunction((ODataFunction)odataOperation); } } } 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); } ICountOptionCollection countOptionCollection = feedInstance as ICountOptionCollection; if (countOptionCollection != null && countOptionCollection.TotalCount != null) { feed.Count = countOptionCollection.TotalCount; } } return(feed); }