Skip to content

Commit

Permalink
update changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ElizabethOkerio committed Jul 18, 2023
1 parent 572f91c commit 163a3ef
Showing 1 changed file with 21 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Reflection.Metadata;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Extensions;
Expand All @@ -22,12 +21,10 @@
using Microsoft.AspNetCore.OData.Query.Container;
using Microsoft.AspNetCore.OData.Results;
using Microsoft.AspNetCore.OData.Routing;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OData;
using Microsoft.OData.Edm;
using Microsoft.OData.ModelBuilder.Capabilities.V1;
using Microsoft.OData.UriParser;

namespace Microsoft.AspNetCore.OData.Formatter.Serialization
Expand Down Expand Up @@ -99,38 +96,39 @@ public override async Task WriteObjectInlineAsync(object graph, IEdmTypeReferenc
throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, ResourceSet));
}

IAsyncEnumerable<object> asyncEnumerable = null;
IEnumerable enumerable = null;

if (writeContext.Type != null && writeContext.Type.IsGenericType && writeContext.Type?.GetGenericTypeDefinition() == typeof(IAsyncEnumerable<>))
{
IAsyncEnumerable<object> asyncEnumerable = graph as IAsyncEnumerable<object>; // Data to serialize
asyncEnumerable = graph as IAsyncEnumerable<object>; // Data to serialize

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

await WriteResourceSetAsync(asyncEnumerable, expectedType, writer, writeContext).ConfigureAwait(false);
}
else
{
IEnumerable enumerable = graph as IEnumerable; // Data to serialize
enumerable = graph as IEnumerable; // Data to serialize

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

await WriteResourceSetAsync(enumerable, expectedType, writer, writeContext).ConfigureAwait(false);
}
await WriteResourceSetAsync(enumerable, asyncEnumerable, expectedType, writer, writeContext).ConfigureAwait(false);
}

private async Task WriteResourceSetAsync(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer,
private async Task WriteResourceSetAsync(IEnumerable enumerable, IAsyncEnumerable<object> asyncEnumerable, IEdmTypeReference resourceSetType, ODataWriter writer,
ODataSerializerContext writeContext)
{
Contract.Assert(writer != null);
Contract.Assert(writeContext != null);
Contract.Assert(enumerable != null);
Contract.Assert((enumerable != null) || (asyncEnumerable != null));
Contract.Assert(resourceSetType != null);

IEdmStructuredTypeReference elementType = GetResourceType(resourceSetType);
Expand Down Expand Up @@ -169,72 +167,23 @@ private async Task WriteResourceSetAsync(IEnumerable enumerable, IEdmTypeReferen
await writer.WriteStartAsync(resourceSet).ConfigureAwait(false);
object lastResource = null;

foreach (object item in enumerable)
{
lastResource = item;

await WriteResourceSetAsync(item, elementType, isUntypedCollection, resourceSetType, writer, resourceSerializer, writeContext);
}

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

resourceSet.NextPageLink = nextLinkGenerator(lastResource);

await writer.WriteEndAsync().ConfigureAwait(false);
}

private async Task WriteResourceSetAsync(IAsyncEnumerable<object> enumerable, IEdmTypeReference resourceSetType, ODataWriter writer,
ODataSerializerContext writeContext)
{
Contract.Assert(writer != null);
Contract.Assert(writeContext != null);
Contract.Assert(enumerable != null);
Contract.Assert(resourceSetType != null);

IEdmStructuredTypeReference elementType = GetResourceType(resourceSetType);
ODataResourceSet resourceSet = CreateResourceSet(enumerable as IEnumerable, resourceSetType.AsCollection(), writeContext);

Func<object, Uri> nextLinkGenerator = GetNextLinkGenerator(resourceSet, enumerable as IEnumerable, writeContext);

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

IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase;
if (entitySet == null)
if (asyncEnumerable != null)
{
resourceSet.SetSerializationInfo(new ODataResourceSerializationInfo
await foreach (object item in asyncEnumerable)
{
IsFromCollection = true,
NavigationSourceEntityTypeName = elementType.FullName(),
NavigationSourceKind = EdmNavigationSourceKind.UnknownEntitySet,
NavigationSourceName = null
});
}
lastResource = item;

IODataEdmTypeSerializer resourceSerializer = SerializerProvider.GetEdmTypeSerializer(elementType);
if (resourceSerializer == null)
{
throw new SerializationException(
Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName()));
await WriteResourceSetAsync(item, elementType, isUntypedCollection, resourceSetType, writer, resourceSerializer, writeContext);
}
}

bool isUntypedCollection = resourceSetType.IsCollectionUntyped();

// set the nextpagelink to null to support JSON odata.streaming.
resourceSet.NextPageLink = null;
await writer.WriteStartAsync(resourceSet).ConfigureAwait(false);
object lastResource = null;
await foreach (object item in enumerable)
else
{
lastResource = item;
foreach (object item in enumerable)
{
lastResource = item;

await WriteResourceSetAsync(item, elementType, isUntypedCollection, resourceSetType, writer, resourceSerializer, writeContext);
await WriteResourceSetAsync(item, elementType, isUntypedCollection, resourceSetType, writer, resourceSerializer, writeContext);
}
}

// Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(resourceSet),
Expand Down

0 comments on commit 163a3ef

Please sign in to comment.