Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/update bulk ops serialization #2697

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Microsoft.AspNet.OData.Shared/DeltaSetOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Microsoft.AspNet.OData
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[NonValidatingParameterBinding]
internal class DeltaSet<TStructuralType> : Collection<IDeltaSetItem>, IDeltaSet where TStructuralType : class
public class DeltaSet<TStructuralType> : Collection<IDeltaSetItem>, IDeltaSet where TStructuralType : class
{
private Type _clrType;
private IList<string> _keys;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ internal static bool CanWriteType(
ODataPayloadKind? payloadKind;

Type elementType;
if (typeof(IEdmObject).IsAssignableFrom(type) ||
if (typeof(IEdmObject).IsAssignableFrom(type) ||
typeof(IDeltaSet).IsAssignableFrom(type) ||
(TypeHelper.IsCollection(type, out elementType) && typeof(IEdmObject).IsAssignableFrom(elementType)))
{
payloadKind = GetEdmObjectPayloadKind(type, internalRequest);
Expand Down Expand Up @@ -156,7 +157,16 @@ internal static void WriteToStream(

ODataMessageWriterSettings writerSettings = internalRequest.WriterSettings;
writerSettings.BaseUri = baseAddress;
writerSettings.Version = version;

if (serializer.ODataPayloadKind == ODataPayloadKind.Delta)
{
writerSettings.Version = ODataVersion.V401;
}
else
{
writerSettings.Version = version;
}

writerSettings.Validations = writerSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

string metadataLink = internaUrlHelper.CreateODataLink(MetadataSegment.Instance);
Expand Down Expand Up @@ -207,6 +217,7 @@ internal static void WriteToStream(
writeContext.Path = path;
writeContext.MetadataLevel = metadataLevel;
writeContext.QueryOptions = internalRequest.Context.QueryOptions;
writeContext.Type = type;
ElizabethOkerio marked this conversation as resolved.
Show resolved Hide resolved

//Set the SelectExpandClause on the context if it was explicitly specified.
if (selectExpandDifferentFromQueryOptions != null)
Expand Down Expand Up @@ -251,7 +262,7 @@ internal static void WriteToStream(
{
return ODataPayloadKind.ResourceSet;
}
else if (typeof(IEdmChangedObject).IsAssignableFrom(elementType))
else if (typeof(IDeltaSetItem).IsAssignableFrom(elementType) || typeof(IEdmChangedObject).IsAssignableFrom(elementType))
{
return ODataPayloadKind.Delta;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ internal ODataSerializer GetODataPayloadSerializerImpl(Type type, Func<IEdmModel
{
return _rootContainer.GetRequiredService<ODataMetadataSerializer>();
}
else if (TypeHelper.IsTypeAssignableFrom(typeof(IDeltaSet), type))
{
return _rootContainer.GetRequiredService<ODataDeltaFeedSerializer>();
}

// Get the model. Using a Func<IEdmModel> to delay evaluation of the model
// until after the above checks have passed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
//------------------------------------------------------------------------------

using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using Microsoft.AspNet.OData.Builder;
Expand All @@ -25,6 +28,7 @@ namespace Microsoft.AspNet.OData.Formatter.Serialization
public class ODataDeltaFeedSerializer : ODataEdmTypeSerializer
{
private const string DeltaFeed = "deltafeed";
IEdmStructuredTypeReference _elementType;

/// <summary>
/// Initializes a new instance of <see cref="ODataDeltaFeedSerializer"/>.
Expand Down Expand Up @@ -60,6 +64,7 @@ public override void WriteObject(object graph, Type type, ODataMessageWriter mes
}

IEdmTypeReference feedType = writeContext.GetEdmType(graph, type);

Contract.Assert(feedType != null);

IEdmEntityTypeReference entityType = GetResourceType(feedType).AsEntity();
Expand Down Expand Up @@ -93,6 +98,7 @@ public override async Task WriteObjectAsync(object graph, Type type, ODataMessag
}

IEdmTypeReference feedType = writeContext.GetEdmType(graph, type);

Contract.Assert(feedType != null);

IEdmEntityTypeReference entityType = GetResourceType(feedType).AsEntity();
Expand Down Expand Up @@ -186,6 +192,7 @@ private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, OData
Contract.Assert(feedType != null);

IEdmStructuredTypeReference elementType = GetResourceType(feedType);
_elementType = elementType;

if (elementType.IsComplex())
{
Expand Down Expand Up @@ -234,13 +241,9 @@ private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, OData
}

lastResource = entry;
IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
if (edmChangedObject == null)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
}
EdmDeltaEntityKind deltaEntityKind = GetDeltaEntityKind(enumerable, entry, writeContext);

switch (edmChangedObject.DeltaKind)
switch (deltaEntityKind)
{
case EdmDeltaEntityKind.DeletedEntry:
WriteDeltaDeletedEntry(entry, writer, writeContext);
Expand All @@ -254,6 +257,7 @@ private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, OData
case EdmDeltaEntityKind.Entry:
{
ODataResourceSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataResourceSerializer;

if (entrySerializer == null)
{
throw new SerializationException(
Expand Down Expand Up @@ -289,6 +293,7 @@ private async Task WriteFeedAsync(IEnumerable enumerable, IEdmTypeReference feed
Contract.Assert(feedType != null);

IEdmStructuredTypeReference elementType = GetResourceType(feedType);
_elementType = elementType;

if (elementType.IsComplex())
{
Expand Down Expand Up @@ -337,13 +342,9 @@ private async Task WriteFeedAsync(IEnumerable enumerable, IEdmTypeReference feed
}

lastResource = entry;
IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
if (edmChangedObject == null)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
}
EdmDeltaEntityKind deltaEntityKind = GetDeltaEntityKind(enumerable, entry, writeContext);

switch (edmChangedObject.DeltaKind)
switch (deltaEntityKind)
{
case EdmDeltaEntityKind.DeletedEntry:
await WriteDeltaDeletedEntryAsync(entry, writer, writeContext);
Expand Down Expand Up @@ -441,13 +442,25 @@ public virtual ODataDeltaResourceSet CreateODataDeltaFeed(IEnumerable feedInstan
/// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
public virtual void WriteDeltaDeletedEntry(object graph, ODataWriter writer, ODataSerializerContext writeContext)
{
ODataDeletedResource deletedResource = GetDeletedResource(graph);
ODataResourceSerializer serializer = SerializerProvider.GetEdmTypeSerializer(_elementType) as ODataResourceSerializer;

if (serializer == null)
{
throw new SerializationException(
Error.Format(SRResources.TypeCannotBeSerialized, _elementType.FullName()));
}

ResourceContext resourceContext = serializer.GetResourceContext(graph, writeContext);
SelectExpandNode selectExpandNode = serializer.CreateSelectExpandNode(resourceContext);

if (deletedResource != null)
if (selectExpandNode != null)
ElizabethOkerio marked this conversation as resolved.
Show resolved Hide resolved
{
ODataDeletedResource deletedResource = GetDeletedResource(graph, resourceContext, serializer, selectExpandNode, writeContext.IsUntyped);
writer.WriteStart(deletedResource);
serializer.WriteDeltaComplexProperties(selectExpandNode, resourceContext, writer);
writer.WriteEnd();
}

}

/// <summary>
Expand All @@ -459,10 +472,22 @@ public virtual void WriteDeltaDeletedEntry(object graph, ODataWriter writer, ODa
/// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
public virtual async Task WriteDeltaDeletedEntryAsync(object graph, ODataWriter writer, ODataSerializerContext writeContext)
{
ODataDeletedResource deletedResource = GetDeletedResource(graph);
if (deletedResource != null)
ODataResourceSerializer serializer = SerializerProvider.GetEdmTypeSerializer(_elementType) as ODataResourceSerializer;

if (serializer == null)
{
throw new SerializationException(
Error.Format(SRResources.TypeCannotBeSerialized, _elementType.FullName()));
}

ResourceContext resourceContext = serializer.GetResourceContext(graph, writeContext);
SelectExpandNode selectExpandNode = serializer.CreateSelectExpandNode(resourceContext);

if (selectExpandNode != null)
{
ODataDeletedResource deletedResource = GetDeletedResource(graph, resourceContext, serializer, selectExpandNode, writeContext.IsUntyped);
await writer.WriteStartAsync(deletedResource);
await serializer.WriteDeltaComplexPropertiesAsync(selectExpandNode, resourceContext, writer);
await writer.WriteEndAsync();
}
}
Expand Down Expand Up @@ -531,22 +556,41 @@ public async Task WriteDeltaLinkAsync(object graph, ODataWriter writer, ODataSer
}
}

private ODataDeletedResource GetDeletedResource(object graph)
private ODataDeletedResource GetDeletedResource(object graph, ResourceContext resourceContext, ODataResourceSerializer serializer, SelectExpandNode selectExpandNode, bool isUntyped)
{
EdmDeltaDeletedEntityObject edmDeltaDeletedEntity = graph as EdmDeltaDeletedEntityObject;
if (edmDeltaDeletedEntity == null)
string navigationSource;
ODataDeletedResource deletedResource = serializer.CreateDeletedResource(selectExpandNode, resourceContext);

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

deletedResource.Id = StringToUri(edmDeltaDeletedEntity.Id ?? string.Empty);
ElizabethOkerio marked this conversation as resolved.
Show resolved Hide resolved
deletedResource.Reason = edmDeltaDeletedEntity.Reason;
navigationSource = edmDeltaDeletedEntity.NavigationSource?.Name;
}
else
{
IDeltaDeletedEntityObject deltaDeletedEntity = graph as IDeltaDeletedEntityObject;
if (deltaDeletedEntity == null)
{
throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName));
}

Uri id = StringToUri(edmDeltaDeletedEntity.Id);
ODataDeletedResource deletedResource = new ODataDeletedResource(id, edmDeltaDeletedEntity.Reason);
deletedResource.Id = deltaDeletedEntity.Id;
deletedResource.Reason = deltaDeletedEntity.Reason;
navigationSource = deltaDeletedEntity.NavigationSource;
}

if (edmDeltaDeletedEntity.NavigationSource != null)
if (navigationSource != null)
{
ODataResourceSerializationInfo serializationInfo = new ODataResourceSerializationInfo
{
NavigationSourceName = edmDeltaDeletedEntity.NavigationSource.Name
NavigationSourceName = navigationSource
};
deletedResource.SetSerializationInfo(serializationInfo);
}
Expand Down Expand Up @@ -621,5 +665,35 @@ internal static Uri StringToUri(string uriString)

return uri;
}

private EdmDeltaEntityKind GetDeltaEntityKind(IEnumerable enumerable, object entry, ODataSerializerContext writeContext)
{
EdmDeltaEntityKind deltaEntityKind;

if (writeContext.IsUntyped)
{
IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;

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

deltaEntityKind = edmChangedObject.DeltaKind;
}
else
{
IDeltaSetItem deltaSetItem = entry as IDeltaSetItem;

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

deltaEntityKind = deltaSetItem.DeltaKind;
}

return deltaEntityKind;
}
}
}
Loading