From 163a3efe538871bbb3095ba61d97f287187f955b Mon Sep 17 00:00:00 2001 From: Elizabeth Okerio Date: Tue, 18 Jul 2023 12:26:21 +0300 Subject: [PATCH] update changes --- .../ODataResourceSetSerializer.cs | 93 +++++-------------- 1 file changed, 21 insertions(+), 72 deletions(-) diff --git a/src/Microsoft.AspNetCore.OData/Formatter/Serialization/ODataResourceSetSerializer.cs b/src/Microsoft.AspNetCore.OData/Formatter/Serialization/ODataResourceSetSerializer.cs index 53086361f..32f94f883 100644 --- a/src/Microsoft.AspNetCore.OData/Formatter/Serialization/ODataResourceSetSerializer.cs +++ b/src/Microsoft.AspNetCore.OData/Formatter/Serialization/ODataResourceSetSerializer.cs @@ -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; @@ -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 @@ -99,38 +96,39 @@ public override async Task WriteObjectInlineAsync(object graph, IEdmTypeReferenc throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, ResourceSet)); } + IAsyncEnumerable asyncEnumerable = null; + IEnumerable enumerable = null; + if (writeContext.Type != null && writeContext.Type.IsGenericType && writeContext.Type?.GetGenericTypeDefinition() == typeof(IAsyncEnumerable<>)) { - IAsyncEnumerable asyncEnumerable = graph as IAsyncEnumerable; // Data to serialize + asyncEnumerable = graph as IAsyncEnumerable; // 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 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); @@ -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 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 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),