public void ConvertFeed(Uri relativeODataUri, Uri relativeSodaUri, JsonPayload jsonPayload, DateTimeOffset feedUpdateTime) { var jsonObject = jsonPayload.JsonObject; var entries = jsonObject.PropertyValue<JArray>("entries"); var meta = jsonObject.PropertyValue<JObject>("meta"); var view = meta.PropertyValue<JObject>("view"); IList<string> fieldsToIgnore; var model = BuildModel(view, out fieldsToIgnore); var entitySet = model.EntityContainers.Single().EntitySets().Single(); var settings = new ODataMessageWriterSettings { Indent = true, }; using (var writer = new ODataMessageWriter(Message, settings, model)) { var feedWriter = writer.CreateODataFeedWriter(); var feed = new ODataFeed(); feed.SetAnnotation(new AtomFeedMetadata { Updated = feedUpdateTime, }); feed.Id = new Uri(ODataEndpointUri, relativeODataUri.OriginalString).OriginalString; feedWriter.WriteStart(feed); foreach (var entry in entries.Cast<JObject>()) { var entryMetadata = new ODataEntry(); entryMetadata.Id = (string) ((JValue) entry.Property("id").Value).Value; entryMetadata.TypeName = entitySet.ElementType.FullName(); entryMetadata.Properties = ConvertProperties(entry, fieldsToIgnore); entryMetadata.SetAnnotation(new AtomEntryMetadata { Updated = ConvertDateTimeOffset(entry.PrimitivePropertyValue<long>("updated_at")), Published = ConvertDateTimeOffset(entry.PrimitivePropertyValue<long>("created_at")), }); feedWriter.WriteStart(entryMetadata); feedWriter.WriteEnd(); } feedWriter.WriteEnd(); } }
public static MaterializerFeed CreateFeed(ODataFeed feed, IEnumerable<ODataEntry> entries) { if (entries == null) { entries = Enumerable.Empty<ODataEntry>(); } else { feed.SetAnnotation<IEnumerable<ODataEntry>>(entries); } return new MaterializerFeed(feed, entries); }
/// <summary> /// Reads the start of a feed; this includes feed-level properties if the version permits it. /// </summary> /// <param name="feed">The <see cref="ODataFeed"/> instance to fill with the data read.</param> /// <param name="isResultsWrapperExpected">A flag indicating whether we expect the results wrapper for feeds to be present.</param> /// <param name="isExpandedLinkContent">true if the feed is inside an expanded link.</param> /// <remarks> /// Pre-Condition: JsonNodeType.StartArray: for a feed without 'results' wrapper /// JsonNodeType.StartObject: for a feed wrapped with 'results' wrapper /// Post-Condition: Any start node The first item in the feed /// JsonNodeType.EndArray: The end of the feed /// </remarks> internal void ReadFeedStart(ODataFeed feed, bool isResultsWrapperExpected, bool isExpandedLinkContent) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(feed != null, "feed != null"); Debug.Assert( isResultsWrapperExpected && this.JsonReader.NodeType == JsonNodeType.StartObject || !isResultsWrapperExpected && this.JsonReader.NodeType == JsonNodeType.StartArray, "Pre-Condition: expected JsonNodeType.StartObject or JsonNodeType.StartArray"); this.JsonReader.AssertNotBuffering(); if (isResultsWrapperExpected) { this.JsonReader.ReadNext(); // skip over the StartObject node // read all the properties until we get to the 'results' property while (true) { if (this.JsonReader.NodeType != JsonNodeType.Property) { Debug.Assert(this.JsonReader.NodeType == JsonNodeType.EndObject, "Only properties and end-of-object should be returned here."); // we only expect properties until we find the 'results' property throw new ODataException(o.Strings.ODataJsonEntryAndFeedDeserializer_ExpectedFeedResultsPropertyNotFound); } // read the property name and move the reader onto the start of the property value string propertyName = this.JsonReader.ReadPropertyName(); if (string.CompareOrdinal(JsonConstants.ODataResultsName, propertyName) == 0) { break; } this.ReadFeedProperty(feed, propertyName, isExpandedLinkContent); } // At this point the reader is guaranteed to be positioned over the value of the 'results' property } // at this point the reader is positioned on the start array node for the feed contents; if (this.JsonReader.NodeType != JsonNodeType.StartArray) { throw new ODataException(o.Strings.ODataJsonEntryAndFeedDeserializer_CannotReadFeedContentStart(this.JsonReader.NodeType)); } this.JsonReader.ReadStartArray(); this.JsonReader.AssertNotBuffering(); this.AssertJsonCondition(JsonNodeType.EndArray, JsonNodeType.PrimitiveValue, JsonNodeType.StartObject, JsonNodeType.StartArray); }
private void WriteFeed(object graph, ODataWriter writer, ODataSerializerContext writeContext) { ODataSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(_edmCollectionType.ElementType()); if (entrySerializer == null) { throw Error.NotSupported(SRResources.TypeCannotBeSerialized, _edmCollectionType.ElementType(), typeof(ODataMediaTypeFormatter).Name); } Contract.Assert(entrySerializer.ODataPayloadKind == ODataPayloadKind.Entry); IEnumerable enumerable = graph as IEnumerable; // Data to serialize if (enumerable != null) { ODataFeed feed = new ODataFeed(); if (writeContext.EntitySet != null) { IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet); Uri feedSelfLink = linkBuilder.BuildFeedSelfLink(new FeedContext(writeContext.EntitySet, writeContext.UrlHelper, graph)); if (feedSelfLink != null) { feed.SetAnnotation(new AtomFeedMetadata() { SelfLink = new AtomLinkMetadata() { Relation = SelfLinkRelation, Href = feedSelfLink } }); } } // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ? feed.Id = FeedNamespace + _edmCollectionType.FullName(); // If we have more OData format specific information apply it now. ODataResult odataFeedAnnotations = graph as ODataResult; if (odataFeedAnnotations != null) { feed.Count = odataFeedAnnotations.Count; feed.NextPageLink = odataFeedAnnotations.NextPageLink; } writer.WriteStart(feed); foreach (object entry in enumerable) { entrySerializer.WriteObjectInline(entry, writer, writeContext); } writer.WriteEnd(); } }
protected override void EndFeed(ODataFeed feed) { if ((base.ParentNavigationLink == null) || this.jsonOutputContext.WritingResponse) { this.jsonOutputContext.JsonWriter.EndArrayScope(); Uri nextPageLink = feed.NextPageLink; if ((this.jsonOutputContext.Version >= ODataVersion.V2) && this.jsonOutputContext.WritingResponse) { this.WriteFeedCount(feed); if (nextPageLink != null) { this.jsonOutputContext.JsonWriter.WriteName("__next"); this.jsonOutputContext.JsonWriter.WriteValue(this.jsonEntryAndFeedSerializer.UriToAbsoluteUriString(nextPageLink)); } this.jsonOutputContext.JsonWriter.EndObjectScope(); } } }
ODataResponse IODataView.CreateView() { var oDataResponse = new ODataResponse(); var messageWriter = new ODataMessageWriter(oDataResponse); var entryWriter = messageWriter.CreateODataFeedWriter(); var feed = new ODataFeed() { Count = Videos.Count, Id = "Hypermedia-Learning" }; var atomFeed = feed.Atom(); atomFeed.Title = "Hypermedia API - " + PageTitle; entryWriter.WriteStart(feed); foreach (var video in Videos) { var oDataEntry = new ODataEntry() {}; var atom = oDataEntry.Atom(); atom.Title = "Video : " + video.Link.Title; atom.Summary = video.Description; entryWriter.WriteStart(oDataEntry); entryWriter.WriteEnd(); } foreach (var item in Community) { var oDataEntry = new ODataEntry() { }; var atom = oDataEntry.Atom(); atom.Title = "Community : " + item.Link.Title; atom.Summary = item.Description; entryWriter.WriteStart(oDataEntry); entryWriter.WriteEnd(); } entryWriter.WriteEnd(); entryWriter.Flush(); oDataResponse.GetStream().Position = 0; return oDataResponse; }
public void WriteObjectInline_Sets_InlineCount_OnWriteStart() { // Arrange IEnumerable instance = new object[0]; ODataFeed feed = new ODataFeed { Count = 1000 }; Mock<ODataFeedSerializer> serializer = new Mock<ODataFeedSerializer>(new DefaultODataSerializerProvider()); serializer.CallBase = true; serializer.Setup(s => s.CreateODataFeed(instance, _customersType, _writeContext)).Returns(feed); var mockWriter = new Mock<ODataWriter>(); mockWriter.Setup(m => m.WriteStart(It.Is<ODataFeed>(f => f.Count == 1000))).Verifiable(); // Act serializer.Object.WriteObjectInline(instance, _customersType, mockWriter.Object, _writeContext); // Assert mockWriter.Verify(); }
/// <summary> /// Start writing a feed - implementation of the actual functionality. /// </summary> /// <param name="feed">The feed to write.</param> private void WriteStartFeedImplementation(ODataFeed feed) { this.CheckForNavigationLinkWithContent(ODataPayloadKind.Feed); this.EnterScope(WriterState.Feed, feed); if (!this.SkipWriting) { this.InterceptException(() => { WriterValidationUtils.ValidateFeedAtStart(feed); // Verify inline count if (feed.Count.HasValue) { // Check that Count is not set for expanded links if (!this.IsTopLevel) { throw new ODataException(Strings.ODataWriterCore_OnlyTopLevelFeedsSupportInlineCount); } // Check that Count is not set for requests if (!this.outputContext.WritingResponse) { this.ThrowODataException(Strings.ODataWriterCore_InlineCountInRequest, feed); } // Verify version requirements ODataVersionChecker.CheckCount(this.outputContext.Version); } this.StartFeed(feed); }); } }
/// <summary> /// Create a new feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> /// <returns>The newly create scope.</returns> protected abstract FeedScope CreateFeedScope(ODataFeed feed, bool skipWriting);
/// <summary> /// Start writing a feed. /// </summary> /// <param name="feed">The feed to write.</param> protected abstract void StartFeed(ODataFeed feed);
/// <summary> /// Start writing a feed. /// </summary> /// <param name="feed">Feed/collection to write.</param> public sealed override void WriteStart(ODataFeed feed) { this.VerifyCanWriteStartFeed(true, feed); this.WriteStartFeedImplementation(feed); }
private void ReadFeedStart(bool isExpandedLinkContent) { ODataFeed feed = new ODataFeed(); if ((this.jsonEntryAndFeedDeserializer.JsonReader.NodeType != JsonNodeType.StartObject) && (this.jsonEntryAndFeedDeserializer.JsonReader.NodeType != JsonNodeType.StartArray)) { throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonReader_CannotReadFeedStart(this.jsonEntryAndFeedDeserializer.JsonReader.NodeType)); } bool isResultsWrapperExpected = this.jsonEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.StartObject; this.jsonEntryAndFeedDeserializer.ReadFeedStart(feed, isResultsWrapperExpected, isExpandedLinkContent); this.EnterScope(ODataReaderState.FeedStart, feed, base.CurrentEntityType); this.CurrentJsonScope.FeedHasResultsWrapper = isResultsWrapperExpected; }
protected abstract void EndFeed(ODataFeed feed);
/// <summary> /// Reads the start of a feed and sets up the reader state correctly. /// </summary> /// <param name="isExpandedLinkContent">true if the feed is inside an expanded link.</param> /// <remarks> /// Pre-Condition: The first node of the feed; this method will throw if the node is not /// JsonNodeType.StartArray: a feed without 'results' wrapper /// JsonNodeType.StartObject: a feed with 'results' wrapper /// Post-Condition: The reader is positioned on the first item in the feed, or on the end array of the feed. /// </remarks> private void ReadFeedStart(bool isExpandedLinkContent) { Debug.Assert( this.jsonInputContext.ReadingResponse || this.State != ODataReaderState.NavigationLinkStart, "Expanded navigation links in requests should not call this method."); ODataFeed feed = new ODataFeed(); if (this.jsonEntryAndFeedDeserializer.JsonReader.NodeType != JsonNodeType.StartObject && this.jsonEntryAndFeedDeserializer.JsonReader.NodeType != JsonNodeType.StartArray) { throw new ODataException(o.Strings.ODataJsonReader_CannotReadFeedStart(this.jsonEntryAndFeedDeserializer.JsonReader.NodeType)); } bool feedHasResultsWrapper = this.jsonEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.StartObject; // read the start of the feed until we determine the next item not belonging to the feed this.jsonEntryAndFeedDeserializer.ReadFeedStart(feed, feedHasResultsWrapper, isExpandedLinkContent); this.EnterScope(ODataReaderState.FeedStart, feed, this.CurrentEntityType); // set the flag so that we know whether to also read '}' when reading the end of the feed this.CurrentJsonScope.FeedHasResultsWrapper = feedHasResultsWrapper; this.jsonEntryAndFeedDeserializer.AssertJsonCondition(JsonNodeType.EndArray, JsonNodeType.PrimitiveValue, JsonNodeType.StartObject, JsonNodeType.StartArray); }
internal FeedScope(ODataFeed feed, bool skipWriting) : base(ODataWriterCore.WriterState.Feed, feed, skipWriting) { }
/// <summary> /// Initializes a new instance of <see cref="ODataFeedWithEntries"/>. /// </summary> /// <param name="item">The wrapped item.</param> public ODataFeedWithEntries(ODataFeed item) : base(item) { Entries = new List<ODataEntryWithNavigationLinks>(); }
/// <summary> /// Creates an OData feed response containing a list of entries for a particular type of entity /// </summary> /// <param name="resultsGraph">The RDF graph containing the SPARQL results</param> /// <param name="entityType">The fully qualified domain name for the type of entity to be written</param> /// <param name="resultsCount">The count of the total number of results that the server can provide</param> /// <param name="originalQueryModel">The SPARQL query that was executed to generate this graph</param> public void CreateFeedFromGraph(IGraph resultsGraph, string entityType, int resultsCount, SparqlModel originalQueryModel = null) { var msgWriter = new ODataMessageWriter(_response, _writerSettings, _map.Model); var feedWriter = msgWriter.CreateODataFeedWriter(); var entries = new List<ODataEntry>(); var typeUri = _map.GetUriForType(entityType); if (!String.IsNullOrEmpty(typeUri)) { var predNode = resultsGraph.CreateUriNode(UriFactory.Create(RdfConstants.RdfType)); var objNode = resultsGraph.CreateUriNode(UriFactory.Create(typeUri)); if (originalQueryModel == null || originalQueryModel.Ordering == null) { // No sorting required, just iterate all instances foreach (var instanceTriple in resultsGraph.GetTriplesWithPredicateObject(predNode, objNode)) { var instanceUri = (instanceTriple.Subject as IUriNode).Uri; entries.Add(CreateODataEntry(resultsGraph, instanceUri.ToString(), entityType)); } } else { // We need to apply the same sort criteria to this graph to ensure // that the ODATA results are properly sorted. // NOTE: This will only work if all the properties used in the original query // are present in the graph - this could be a problem with more complex traversals // and the query may instead need to be rewritten / regenerated to extract only // the required sort properties. originalQueryModel.IsDescribe = false; var resultsTable = resultsGraph.ExecuteQuery(originalQueryModel.GetSparqlRepresentation()) as SparqlResultSet; var targetVariable= originalQueryModel.SelectVariables[0]; foreach (var result in resultsTable.Results) { var instanceUriNode = result[targetVariable] as IUriNode; if (instanceUriNode != null) { entries.Add(CreateODataEntry(resultsGraph, instanceUriNode.Uri.ToString(), entityType)); } } } } var feed = new ODataFeed {Id = _baseUri + _map.GetTypeSet(entityType)}; if (_writerSettings.Version >= ODataVersion.V2) { feed.Count = resultsCount; } if (originalQueryModel != null) { feed.NextPageLink = GetNextPageLink(originalQueryModel); } feedWriter.WriteStart(feed); foreach (var entry in entries) { feedWriter.WriteStart(entry); feedWriter.WriteEnd(); } feedWriter.WriteEnd(); feedWriter.Flush(); }
public sealed override void WriteStart(ODataFeed feed) { this.VerifyCanWriteStartFeed(true, feed); this.WriteStartFeedImplementation(feed); }
protected abstract FeedScope CreateFeedScope(ODataFeed feed, bool skipWriting);
/// <summary> /// Reads the next node in the content of an expanded navigation link which represents a collection and is in a request payload. /// </summary> /// <remarks> /// This method deals with all the special cases in request payload expanded navigation link for collections. /// It should be called when the array start of the content of such a link was already read. /// It should be called in these cases: /// - Start of the navigation link (to report the first content item of it) /// - Entity reference link was reported (to report the next item of the navigation link content) /// - Feed end was reported, to report the next non-entry item in the navigation link content /// - Entry end was reported, to determine if the next entry should be reported, or if the feed should be closed. /// </remarks> private void ReadExpandedCollectionNavigationLinkContentInRequest() { Debug.Assert(!this.jsonInputContext.ReadingResponse, "This method should only be called for requests."); // We are positioned on the next item in the feed array, so it can be either an entity reference link, or expanded entry if (this.jsonEntryAndFeedDeserializer.IsEntityReferenceLink()) { if (this.State == ODataReaderState.FeedStart) { Debug.Assert( this.CurrentJsonScope.FeedInExpandedNavigationLinkInRequest, "Feed inside an expanded navigation link in request is expected here."); // If it's an entity reference link and we are currently inside a feed (which is the expanded feed), we need to close that feed first this.ReplaceScope(ODataReaderState.FeedEnd); } else { // If we're not in feed, we must be at the navigation link level Debug.Assert(this.State == ODataReaderState.NavigationLinkStart, "Entity reference link can only occur inside a feed or inside a navigation link."); this.CurrentJsonScope.ExpandedNavigationLinkInRequestHasContent = true; // In this case we read the entity reference link and report it // read the entity reference link ODataEntityReferenceLink entityReferenceLink = this.jsonEntryAndFeedDeserializer.ReadEntityReferenceLink(); this.EnterScope(ODataReaderState.EntityReferenceLink, entityReferenceLink, null); } } else if (this.jsonEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.EndArray || this.jsonEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.EndObject) { // End of the expanded navigation link array if (this.State == ODataReaderState.FeedStart) { // If we are inside one of the expanded feeds, end that feed first Debug.Assert( this.CurrentJsonScope.FeedInExpandedNavigationLinkInRequest, "Feed inside an expanded navigation link in request is expected here."); Debug.Assert( this.jsonEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.EndArray, "End of array expected"); this.jsonEntryAndFeedDeserializer.ReadFeedEnd(this.CurrentFeed, this.CurrentJsonScope.FeedHasResultsWrapper, true); this.ReplaceScope(ODataReaderState.FeedEnd); } else { Debug.Assert(this.State == ODataReaderState.NavigationLinkStart, "We should be in a navigation link state."); if (!this.CurrentJsonScope.ExpandedNavigationLinkInRequestHasContent) { // If we haven't found and reported any content for the link yet, we need to report an empty feed. // This is to avoid reporting the link without any content which would be treated as a deferred link // which is invalid in requests. this.CurrentJsonScope.ExpandedNavigationLinkInRequestHasContent = true; this.EnterScope(ODataReaderState.FeedStart, new ODataFeed(), this.CurrentEntityType); this.CurrentJsonScope.FeedInExpandedNavigationLinkInRequest = true; } else { // If the expanded feed ended with entity reference link the information whether the feed was wrapped with // 'results' wrapper will be stored in the NavigationLinkStart scope which is current scope. Here we use it // to know whether to skip only ']' before we skip the character closing the extended feed. if (this.CurrentJsonScope.FeedHasResultsWrapper) { // note that ODataFeed instance passed here is a dummy feed that is not being used anywhere else. var feed = new ODataFeed(); this.jsonEntryAndFeedDeserializer.ReadFeedEnd(feed, true, true); Debug.Assert( feed.Count == null && feed.NextPageLink == null && feed.Id == null, "No feed properties should be set when closing a feed"); } // Here we are reading either the closing ']' of an unwrapped expanded feed or the closing '}' of an // wrapped expanded feed or the closing '}' of a navigation property contents. this.jsonEntryAndFeedDeserializer.JsonReader.Read(); // End the navigation link this.ReadExpandedNavigationLinkEnd(true); } } } else { // The thing we're looking at is not an entity reference link if (this.State == ODataReaderState.FeedStart) { Debug.Assert( this.CurrentJsonScope.FeedInExpandedNavigationLinkInRequest, "Feed inside an expanded navigation link in request is expected here."); if (this.jsonEntryAndFeedDeserializer.JsonReader.NodeType != JsonNodeType.StartObject) { throw new ODataException(o.Strings.ODataJsonReader_CannotReadEntriesOfFeed(this.jsonEntryAndFeedDeserializer.JsonReader.NodeType)); } // If we're already in a feed, read the item as an entry directly this.ReadEntryStart(); } else { Debug.Assert(this.State == ODataReaderState.NavigationLinkStart, "Entity reference link can only occur inside a feed or inside a navigation link."); this.CurrentJsonScope.ExpandedNavigationLinkInRequestHasContent = true; // If we're not yet in a feed, start a new feed, note that this feed has no payload counterpart, it's just necessary for our API this.EnterScope(ODataReaderState.FeedStart, new ODataFeed(), this.CurrentEntityType); this.CurrentJsonScope.FeedInExpandedNavigationLinkInRequest = true; } } }
/// <summary> /// Create a new feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> /// <returns>The newly create scope.</returns> protected override FeedScope CreateFeedScope(ODataFeed feed, bool skipWriting) { return new AtomFeedScope(feed, skipWriting); }
private void ReadExpandedCollectionNavigationLinkContentInRequest() { if (this.jsonEntryAndFeedDeserializer.IsEntityReferenceLink()) { if (this.State == ODataReaderState.FeedStart) { this.ReplaceScope(ODataReaderState.FeedEnd); } else { this.CurrentJsonScope.ExpandedNavigationLinkInRequestHasContent = true; ODataEntityReferenceLink item = this.jsonEntryAndFeedDeserializer.ReadEntityReferenceLink(); this.EnterScope(ODataReaderState.EntityReferenceLink, item, null); } } else if ((this.jsonEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.EndArray) || (this.jsonEntryAndFeedDeserializer.JsonReader.NodeType == JsonNodeType.EndObject)) { if (this.State == ODataReaderState.FeedStart) { this.jsonEntryAndFeedDeserializer.ReadFeedEnd(base.CurrentFeed, this.CurrentJsonScope.FeedHasResultsWrapper, true); this.ReplaceScope(ODataReaderState.FeedEnd); } else if (!this.CurrentJsonScope.ExpandedNavigationLinkInRequestHasContent) { this.CurrentJsonScope.ExpandedNavigationLinkInRequestHasContent = true; this.EnterScope(ODataReaderState.FeedStart, new ODataFeed(), base.CurrentEntityType); this.CurrentJsonScope.FeedInExpandedNavigationLinkInRequest = true; } else { if (this.CurrentJsonScope.FeedHasResultsWrapper) { ODataFeed feed = new ODataFeed(); this.jsonEntryAndFeedDeserializer.ReadFeedEnd(feed, true, true); } this.jsonEntryAndFeedDeserializer.JsonReader.Read(); this.ReadExpandedNavigationLinkEnd(true); } } else if (this.State == ODataReaderState.FeedStart) { if (this.jsonEntryAndFeedDeserializer.JsonReader.NodeType != JsonNodeType.StartObject) { throw new ODataException(Microsoft.Data.OData.Strings.ODataJsonReader_CannotReadEntriesOfFeed(this.jsonEntryAndFeedDeserializer.JsonReader.NodeType)); } this.ReadEntryStart(); } else { this.CurrentJsonScope.ExpandedNavigationLinkInRequestHasContent = true; this.EnterScope(ODataReaderState.FeedStart, new ODataFeed(), base.CurrentEntityType); this.CurrentJsonScope.FeedInExpandedNavigationLinkInRequest = true; } }
/// <summary> /// Constructor to create a new feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> internal AtomFeedScope(ODataFeed feed, bool skipWriting) : base(feed, skipWriting) { DebugUtils.CheckNoExternalCallers(); }
/// <summary> /// Constructor to create a new feed scope. /// </summary> /// <param name="feed">The feed for the new scope.</param> /// <param name="skipWriting">true if the content of the scope to create should not be written.</param> internal FeedScope(ODataFeed feed, bool skipWriting) : base(WriterState.Feed, feed, skipWriting) { DebugUtils.CheckNoExternalCallers(); }
/// <summary> /// Start writing a feed. /// </summary> /// <param name="feed">Feed/collection to write.</param> public abstract void WriteStart(ODataFeed feed);
/// <summary> /// Asynchronously start writing a feed. /// </summary> /// <param name="feed">Feed/collection to write.</param> /// <returns>A task instance that represents the asynchronous write operation.</returns> public sealed override Task WriteStartAsync(ODataFeed feed) { this.VerifyCanWriteStartFeed(false, feed); return TaskUtils.GetTaskForSynchronousOperation(() => this.WriteStartFeedImplementation(feed)); }
/// <summary> /// Asynchronously start writing a feed. /// </summary> /// <param name="feed">Feed/collection to write.</param> /// <returns>A task instance that represents the asynchronous write operation.</returns> public abstract Task WriteStartAsync(ODataFeed feed);
/// <summary> /// Finish writing a feed. /// </summary> /// <param name="feed">The feed to write.</param> protected abstract void EndFeed(ODataFeed feed);
internal void WriteFeedNextPageLink(ODataFeed feed) { Uri nextPageLink = feed.NextPageLink; if (nextPageLink != null) { AtomFeedMetadata annotation = feed.GetAnnotation<AtomFeedMetadata>(); AtomLinkMetadata linkMetadata = ODataAtomWriterMetadataUtils.MergeLinkMetadata((annotation == null) ? null : annotation.NextPageLink, "next", nextPageLink, null, null); this.atomFeedMetadataSerializer.WriteAtomLink(linkMetadata, null); } }
/// <summary> /// Verifies that calling WriteStart feed is valid. /// </summary> /// <param name="synchronousCall">true if the call is to be synchronous; false otherwise.</param> /// <param name="feed">Feed/collection to write.</param> private void VerifyCanWriteStartFeed(bool synchronousCall, ODataFeed feed) { ExceptionUtils.CheckArgumentNotNull(feed, "feed"); this.VerifyNotDisposed(); this.VerifyCallAllowed(synchronousCall); this.StartPayloadInStartState(); }
internal void WriteFeedMetadata(ODataFeed feed, string updatedTime, out bool authorWritten) { AtomFeedMetadata annotation = feed.GetAnnotation<AtomFeedMetadata>(); if (annotation == null) { base.WriteElementWithTextContent("", "id", "http://www.w3.org/2005/Atom", feed.Id); base.WriteEmptyElement("", "title", "http://www.w3.org/2005/Atom"); base.WriteElementWithTextContent("", "updated", "http://www.w3.org/2005/Atom", updatedTime); authorWritten = false; } else { this.atomFeedMetadataSerializer.WriteFeedMetadata(annotation, feed, updatedTime, out authorWritten); } }
public void WriteObjectInline_Writes_CreateODataFeedOutput() { // Arrange IEnumerable instance = new object[0]; ODataFeed feed = new ODataFeed(); Mock<ODataFeedSerializer> serializer = new Mock<ODataFeedSerializer>(new DefaultODataSerializerProvider()); serializer.CallBase = true; serializer.Setup(s => s.CreateODataFeed(instance, _customersType, _writeContext)).Returns(feed); Mock<ODataWriter> writer = new Mock<ODataWriter>(); writer.Setup(s => s.WriteStart(feed)).Verifiable(); // Act serializer.Object.WriteObjectInline(instance, _customersType, writer.Object, _writeContext); // Assert writer.Verify(); }
public abstract void WriteStart(ODataFeed feed);
public void WriteObjectInline_Sets_NextPageLink_OnWriteEnd() { // Arrange IEnumerable instance = new object[0]; ODataFeed feed = new ODataFeed { NextPageLink = new Uri("http://nextlink.com/") }; Mock<ODataFeedSerializer> serializer = new Mock<ODataFeedSerializer>(new DefaultODataSerializerProvider()); serializer.CallBase = true; serializer.Setup(s => s.CreateODataFeed(instance, _customersType, _writeContext)).Returns(feed); var mockWriter = new Mock<ODataWriter>(); mockWriter.Setup(m => m.WriteStart(It.Is<ODataFeed>(f => f.NextPageLink == null))).Verifiable(); mockWriter .Setup(m => m.WriteEnd()) .Callback(() => { Assert.Equal("http://nextlink.com/", feed.NextPageLink.AbsoluteUri); }) .Verifiable(); // Act serializer.Object.WriteObjectInline(instance, _customersType, mockWriter.Object, _writeContext); // Assert mockWriter.Verify(); }
public abstract Task WriteStartAsync(ODataFeed feed);
/// <summary> /// Create the <see cref="ODataFeed"/> to be written for the given feed instance. /// </summary> /// <param name="feedInstance">The instance representing the feed being written.</param> /// <param name="writeContext">The serializer context.</param> /// <returns>The created <see cref="ODataFeed"/> object.</returns> public virtual ODataFeed CreateODataFeed(IEnumerable feedInstance, ODataSerializerContext writeContext) { ODataFeed feed = new ODataFeed(); if (writeContext.EntitySet != null) { IEdmModel model = writeContext.Model; EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(writeContext.EntitySet); FeedContext feedContext = new FeedContext { Request = writeContext.Request, EntitySet = writeContext.EntitySet, Url = writeContext.Url, FeedInstance = feedInstance }; Uri feedSelfLink = linkBuilder.BuildFeedSelfLink(feedContext); if (feedSelfLink != null) { feed.SetAnnotation(new AtomFeedMetadata() { SelfLink = new AtomLinkMetadata() { Relation = "self", Href = feedSelfLink } }); } } // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ? feed.Id = "http://schemas.datacontract.org/2004/07/" + EntityCollectionType.FullName(); // If we have more OData format specific information apply it now, only if we are the root feed. if (!writeContext.IsNested) { PageResult odataFeedAnnotations = feedInstance as PageResult; if (odataFeedAnnotations != null) { feed.Count = odataFeedAnnotations.Count; feed.NextPageLink = odataFeedAnnotations.NextPageLink; } else if (writeContext.Request != null) { feed.NextPageLink = writeContext.Request.GetNextPageLink(); long? inlineCount = writeContext.Request.GetInlineCount(); if (inlineCount.HasValue) { feed.Count = inlineCount.Value; } } } return feed; }
protected abstract void StartFeed(ODataFeed feed);