66//------------------------------------------------------------------------------
77
88using System ;
9+ using System . CodeDom ;
910using System . Collections ;
11+ using System . Collections . Generic ;
1012using System . Diagnostics . Contracts ;
13+ using System . Reflection ;
1114using System . Runtime . Serialization ;
1215using System . Threading . Tasks ;
1316using Microsoft . AspNet . OData . Builder ;
@@ -25,6 +28,7 @@ namespace Microsoft.AspNet.OData.Formatter.Serialization
2528 public class ODataDeltaFeedSerializer : ODataEdmTypeSerializer
2629 {
2730 private const string DeltaFeed = "deltafeed" ;
31+ IEdmStructuredTypeReference _elementType ;
2832
2933 /// <summary>
3034 /// Initializes a new instance of <see cref="ODataDeltaFeedSerializer"/>.
@@ -60,6 +64,7 @@ public override void WriteObject(object graph, Type type, ODataMessageWriter mes
6064 }
6165
6266 IEdmTypeReference feedType = writeContext . GetEdmType ( graph , type ) ;
67+
6368 Contract . Assert ( feedType != null ) ;
6469
6570 IEdmEntityTypeReference entityType = GetResourceType ( feedType ) . AsEntity ( ) ;
@@ -93,6 +98,7 @@ public override async Task WriteObjectAsync(object graph, Type type, ODataMessag
9398 }
9499
95100 IEdmTypeReference feedType = writeContext . GetEdmType ( graph , type ) ;
101+
96102 Contract . Assert ( feedType != null ) ;
97103
98104 IEdmEntityTypeReference entityType = GetResourceType ( feedType ) . AsEntity ( ) ;
@@ -186,6 +192,7 @@ private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, OData
186192 Contract . Assert ( feedType != null ) ;
187193
188194 IEdmStructuredTypeReference elementType = GetResourceType ( feedType ) ;
195+ _elementType = elementType ;
189196
190197 if ( elementType . IsComplex ( ) )
191198 {
@@ -234,13 +241,9 @@ private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, OData
234241 }
235242
236243 lastResource = entry ;
237- IEdmChangedObject edmChangedObject = entry as IEdmChangedObject ;
238- if ( edmChangedObject == null )
239- {
240- throw new SerializationException ( Error . Format ( SRResources . CannotWriteType , GetType ( ) . Name , enumerable . GetType ( ) . FullName ) ) ;
241- }
244+ EdmDeltaEntityKind deltaEntityKind = GetDeltaEntityKind ( enumerable , entry , writeContext ) ;
242245
243- switch ( edmChangedObject . DeltaKind )
246+ switch ( deltaEntityKind )
244247 {
245248 case EdmDeltaEntityKind . DeletedEntry :
246249 WriteDeltaDeletedEntry ( entry , writer , writeContext ) ;
@@ -254,6 +257,7 @@ private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, OData
254257 case EdmDeltaEntityKind . Entry :
255258 {
256259 ODataResourceSerializer entrySerializer = SerializerProvider . GetEdmTypeSerializer ( elementType ) as ODataResourceSerializer ;
260+
257261 if ( entrySerializer == null )
258262 {
259263 throw new SerializationException (
@@ -289,6 +293,7 @@ private async Task WriteFeedAsync(IEnumerable enumerable, IEdmTypeReference feed
289293 Contract . Assert ( feedType != null ) ;
290294
291295 IEdmStructuredTypeReference elementType = GetResourceType ( feedType ) ;
296+ _elementType = elementType ;
292297
293298 if ( elementType . IsComplex ( ) )
294299 {
@@ -337,13 +342,9 @@ private async Task WriteFeedAsync(IEnumerable enumerable, IEdmTypeReference feed
337342 }
338343
339344 lastResource = entry ;
340- IEdmChangedObject edmChangedObject = entry as IEdmChangedObject ;
341- if ( edmChangedObject == null )
342- {
343- throw new SerializationException ( Error . Format ( SRResources . CannotWriteType , GetType ( ) . Name , enumerable . GetType ( ) . FullName ) ) ;
344- }
345+ EdmDeltaEntityKind deltaEntityKind = GetDeltaEntityKind ( enumerable , entry , writeContext ) ;
345346
346- switch ( edmChangedObject . DeltaKind )
347+ switch ( deltaEntityKind )
347348 {
348349 case EdmDeltaEntityKind . DeletedEntry :
349350 await WriteDeltaDeletedEntryAsync ( entry , writer , writeContext ) ;
@@ -441,13 +442,25 @@ public virtual ODataDeltaResourceSet CreateODataDeltaFeed(IEnumerable feedInstan
441442 /// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
442443 public virtual void WriteDeltaDeletedEntry ( object graph , ODataWriter writer , ODataSerializerContext writeContext )
443444 {
444- ODataDeletedResource deletedResource = GetDeletedResource ( graph ) ;
445+ ODataResourceSerializer serializer = SerializerProvider . GetEdmTypeSerializer ( _elementType ) as ODataResourceSerializer ;
446+
447+ if ( serializer == null )
448+ {
449+ throw new SerializationException (
450+ Error . Format ( SRResources . TypeCannotBeSerialized , _elementType . FullName ( ) ) ) ;
451+ }
452+
453+ ResourceContext resourceContext = serializer . GetResourceContext ( graph , writeContext ) ;
454+ SelectExpandNode selectExpandNode = serializer . CreateSelectExpandNode ( resourceContext ) ;
445455
446- if ( deletedResource != null )
456+ if ( selectExpandNode != null )
447457 {
458+ ODataDeletedResource deletedResource = GetDeletedResource ( graph , resourceContext , serializer , selectExpandNode , writeContext . IsUntyped ) ;
448459 writer . WriteStart ( deletedResource ) ;
460+ serializer . WriteDeltaComplexProperties ( selectExpandNode , resourceContext , writer ) ;
449461 writer . WriteEnd ( ) ;
450462 }
463+
451464 }
452465
453466 /// <summary>
@@ -459,10 +472,22 @@ public virtual void WriteDeltaDeletedEntry(object graph, ODataWriter writer, ODa
459472 /// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param>
460473 public virtual async Task WriteDeltaDeletedEntryAsync ( object graph , ODataWriter writer , ODataSerializerContext writeContext )
461474 {
462- ODataDeletedResource deletedResource = GetDeletedResource ( graph ) ;
463- if ( deletedResource != null )
475+ ODataResourceSerializer serializer = SerializerProvider . GetEdmTypeSerializer ( _elementType ) as ODataResourceSerializer ;
476+
477+ if ( serializer == null )
478+ {
479+ throw new SerializationException (
480+ Error . Format ( SRResources . TypeCannotBeSerialized , _elementType . FullName ( ) ) ) ;
481+ }
482+
483+ ResourceContext resourceContext = serializer . GetResourceContext ( graph , writeContext ) ;
484+ SelectExpandNode selectExpandNode = serializer . CreateSelectExpandNode ( resourceContext ) ;
485+
486+ if ( selectExpandNode != null )
464487 {
488+ ODataDeletedResource deletedResource = GetDeletedResource ( graph , resourceContext , serializer , selectExpandNode , writeContext . IsUntyped ) ;
465489 await writer . WriteStartAsync ( deletedResource ) ;
490+ await serializer . WriteDeltaComplexPropertiesAsync ( selectExpandNode , resourceContext , writer ) ;
466491 await writer . WriteEndAsync ( ) ;
467492 }
468493 }
@@ -531,22 +556,41 @@ public async Task WriteDeltaLinkAsync(object graph, ODataWriter writer, ODataSer
531556 }
532557 }
533558
534- private ODataDeletedResource GetDeletedResource ( object graph )
559+ private ODataDeletedResource GetDeletedResource ( object graph , ResourceContext resourceContext , ODataResourceSerializer serializer , SelectExpandNode selectExpandNode , bool isUntyped )
535560 {
536- EdmDeltaDeletedEntityObject edmDeltaDeletedEntity = graph as EdmDeltaDeletedEntityObject ;
537- if ( edmDeltaDeletedEntity == null )
561+ string navigationSource ;
562+ ODataDeletedResource deletedResource = serializer . CreateDeletedResource ( selectExpandNode , resourceContext ) ;
563+
564+ if ( isUntyped )
538565 {
539- throw new SerializationException ( Error . Format ( SRResources . CannotWriteType , GetType ( ) . Name , graph . GetType ( ) . FullName ) ) ;
566+ EdmDeltaDeletedEntityObject edmDeltaDeletedEntity = graph as EdmDeltaDeletedEntityObject ;
567+ if ( edmDeltaDeletedEntity == null )
568+ {
569+ throw new SerializationException ( Error . Format ( SRResources . CannotWriteType , GetType ( ) . Name , graph . GetType ( ) . FullName ) ) ;
570+ }
571+
572+ deletedResource . Id = StringToUri ( edmDeltaDeletedEntity . Id ?? string . Empty ) ;
573+ deletedResource . Reason = edmDeltaDeletedEntity . Reason ;
574+ navigationSource = edmDeltaDeletedEntity . NavigationSource ? . Name ;
540575 }
576+ else
577+ {
578+ IDeltaDeletedEntityObject deltaDeletedEntity = graph as IDeltaDeletedEntityObject ;
579+ if ( deltaDeletedEntity == null )
580+ {
581+ throw new SerializationException ( Error . Format ( SRResources . CannotWriteType , GetType ( ) . Name , graph . GetType ( ) . FullName ) ) ;
582+ }
541583
542- Uri id = StringToUri ( edmDeltaDeletedEntity . Id ) ;
543- ODataDeletedResource deletedResource = new ODataDeletedResource ( id , edmDeltaDeletedEntity . Reason ) ;
584+ deletedResource . Id = deltaDeletedEntity . Id ;
585+ deletedResource . Reason = deltaDeletedEntity . Reason ;
586+ navigationSource = deltaDeletedEntity . NavigationSource ;
587+ }
544588
545- if ( edmDeltaDeletedEntity . NavigationSource != null )
589+ if ( navigationSource != null )
546590 {
547591 ODataResourceSerializationInfo serializationInfo = new ODataResourceSerializationInfo
548592 {
549- NavigationSourceName = edmDeltaDeletedEntity . NavigationSource . Name
593+ NavigationSourceName = navigationSource
550594 } ;
551595 deletedResource . SetSerializationInfo ( serializationInfo ) ;
552596 }
@@ -621,5 +665,35 @@ internal static Uri StringToUri(string uriString)
621665
622666 return uri ;
623667 }
668+
669+ private EdmDeltaEntityKind GetDeltaEntityKind ( IEnumerable enumerable , object entry , ODataSerializerContext writeContext )
670+ {
671+ EdmDeltaEntityKind deltaEntityKind ;
672+
673+ if ( writeContext . IsUntyped )
674+ {
675+ IEdmChangedObject edmChangedObject = entry as IEdmChangedObject ;
676+
677+ if ( edmChangedObject == null )
678+ {
679+ throw new SerializationException ( Error . Format ( SRResources . CannotWriteType , GetType ( ) . Name , enumerable . GetType ( ) . FullName ) ) ;
680+ }
681+
682+ deltaEntityKind = edmChangedObject . DeltaKind ;
683+ }
684+ else
685+ {
686+ IDeltaSetItem deltaSetItem = entry as IDeltaSetItem ;
687+
688+ if ( deltaSetItem == null )
689+ {
690+ throw new SerializationException ( Error . Format ( SRResources . CannotWriteType , GetType ( ) . Name , enumerable . GetType ( ) . FullName ) ) ;
691+ }
692+
693+ deltaEntityKind = deltaSetItem . DeltaKind ;
694+ }
695+
696+ return deltaEntityKind ;
697+ }
624698 }
625699}
0 commit comments