/// <summary> /// Write an entity reference link. /// </summary> /// <param name="parentNavigationLink">The parent navigation link which is being written around the entity reference link.</param> /// <param name="entityReferenceLink">The entity reference link to write.</param> protected override void WriteEntityReferenceInNavigationLinkContent(ODataNavigationLink parentNavigationLink, ODataEntityReferenceLink entityReferenceLink) { Debug.Assert(parentNavigationLink != null, "parentNavigationLink != null"); Debug.Assert(entityReferenceLink != null, "entityReferenceLink != null"); Debug.Assert(!this.jsonLightOutputContext.WritingResponse, "Entity reference links are only supported in request, we should have verified this already."); // In JSON Light, we can only write entity reference links at the beginning of a navigation link in requests; // once we wrote a feed, entity reference links are not allowed anymore (we require all the entity reference // link to come first because of the grouping in the JSON Light wire format). JsonLightNavigationLinkScope navigationLinkScope = (JsonLightNavigationLinkScope)this.CurrentScope; if (navigationLinkScope.FeedWritten) { throw new ODataException(OData.Core.Strings.ODataJsonLightWriter_EntityReferenceLinkAfterFeedInRequest); } if (!navigationLinkScope.EntityReferenceLinkWritten) { // Write the property annotation for the entity reference link(s) this.odataAnnotationWriter.WritePropertyAnnotationName(parentNavigationLink.Name, ODataAnnotationNames.ODataBind); Debug.Assert(parentNavigationLink.IsCollection.HasValue, "parentNavigationLink.IsCollection.HasValue"); if (parentNavigationLink.IsCollection.Value) { this.jsonWriter.StartArrayScope(); } navigationLinkScope.EntityReferenceLinkWritten = true; } Debug.Assert(entityReferenceLink.Url != null, "The entity reference link Url should have been validated by now."); this.jsonWriter.WriteValue(this.jsonLightEntryAndFeedSerializer.UriToString(entityReferenceLink.Url)); }
/// <summary> /// Finish writing a navigation link with content. /// </summary> /// <param name="navigationLink">The navigation link to write.</param> protected override void EndNavigationLinkWithContent(ODataNavigationLink navigationLink) { Debug.Assert(navigationLink != null, "navigationLink != null"); if (!this.jsonLightOutputContext.WritingResponse) { JsonLightNavigationLinkScope navigationLinkScope = (JsonLightNavigationLinkScope)this.CurrentScope; // If we wrote entity reference links for a collection navigation property but no // feed afterwards, we have to now close the array of links. if (navigationLinkScope.EntityReferenceLinkWritten && !navigationLinkScope.FeedWritten && navigationLink.IsCollection.Value) { this.jsonWriter.EndArrayScope(); } // In requests, the navigation link may have multiple entries in multiple feeds in it; if we // wrote at least one feed, close the resulting array here. if (navigationLinkScope.FeedWritten) { Debug.Assert(navigationLink.IsCollection.Value, "navigationLink.IsCollection.Value"); this.jsonWriter.EndArrayScope(); } } }
/// <summary> /// Start writing a feed. /// </summary> /// <param name="feed">The feed to write.</param> protected override void StartFeed(ODataFeed feed) { Debug.Assert(feed != null, "feed != null"); if (this.ParentNavigationLink == null && this.writingParameter) { // Start array which will hold the entries in the feed. this.jsonWriter.StartArrayScope(); } else if (this.ParentNavigationLink == null) { // Top-level feed. // "{" this.jsonWriter.StartObjectScope(); // @odata.context this.jsonLightEntryAndFeedSerializer.WriteFeedContextUri(this.CurrentFeedScope.GetOrCreateTypeContext(this.jsonLightOutputContext.Model, this.jsonLightOutputContext.WritingResponse)); if (this.jsonLightOutputContext.WritingResponse) { // write "odata.actions" metadata IEnumerable <ODataAction> actions = feed.Actions; if (actions != null) { this.jsonLightEntryAndFeedSerializer.WriteOperations(actions.Cast <ODataOperation>(), /*isAction*/ true); } // write "odata.functions" metadata IEnumerable <ODataFunction> functions = feed.Functions; if (functions != null) { this.jsonLightEntryAndFeedSerializer.WriteOperations(functions.Cast <ODataOperation>(), /*isAction*/ false); } // Write the inline count if it's available. this.WriteFeedCount(feed, /*propertyName*/ null); // Write the next link if it's available. this.WriteFeedNextLink(feed, /*propertyName*/ null); // Write the delta link if it's available. this.WriteFeedDeltaLink(feed); } // Write custom instance annotations this.jsonLightEntryAndFeedSerializer.InstanceAnnotationWriter.WriteInstanceAnnotations(feed.InstanceAnnotations, this.CurrentFeedScope.InstanceAnnotationWriteTracker); // "value": this.jsonWriter.WriteValuePropertyName(); // Start array which will hold the entries in the feed. this.jsonWriter.StartArrayScope(); } else { // Expanded feed. Debug.Assert( this.ParentNavigationLink != null && this.ParentNavigationLink.IsCollection.HasValue && this.ParentNavigationLink.IsCollection.Value, "We should have verified that feeds can only be written into IsCollection = true links in requests."); string propertyName = this.ParentNavigationLink.Name; this.ValidateNoDeltaLinkForExpandedFeed(feed); this.ValidateNoCustomInstanceAnnotationsForExpandedFeed(feed); if (this.jsonLightOutputContext.WritingResponse) { // Write the inline count if it's available. this.WriteFeedCount(feed, propertyName); // Write the next link if it's available. this.WriteFeedNextLink(feed, propertyName); // And then write the property name to start the value. this.jsonWriter.WriteName(propertyName); // Start array which will hold the entries in the feed. this.jsonWriter.StartArrayScope(); } else { JsonLightNavigationLinkScope navigationLinkScope = (JsonLightNavigationLinkScope)this.ParentNavigationLinkScope; if (!navigationLinkScope.FeedWritten) { // Close the entity reference link array (if written) if (navigationLinkScope.EntityReferenceLinkWritten) { this.jsonWriter.EndArrayScope(); } // And then write the property name to start the value. this.jsonWriter.WriteName(propertyName); // Start array which will hold the entries in the feed. this.jsonWriter.StartArrayScope(); navigationLinkScope.FeedWritten = true; } } } }