Exemplo n.º 1
0
 protected override void WriteTopLevelElements(IExpandedResult expanded, IEnumerator elements, bool hasMoved)
 {
     if (base.RequestDescription.LinkUri)
     {
         bool needPop = base.PushSegmentForRoot();
         this.WriteLinkCollection(elements, hasMoved);
         base.PopSegmentName(needPop);
     }
     else
     {
         this.collectionWriter = this.writer.CreateODataCollectionWriter();
         ODataCollectionStart collectionStart = new ODataCollectionStart {
             Name = this.ComputeContainerName()
         };
         this.collectionWriter.WriteStart(collectionStart);
         while (hasMoved)
         {
             object       current = elements.Current;
             ResourceType propertyResourceType = (current == null) ? base.RequestDescription.TargetResourceType : WebUtil.GetResourceType(base.Provider, current);
             if (propertyResourceType == null)
             {
                 throw new InvalidOperationException(System.Data.Services.Strings.Serializer_UnsupportedTopLevelType(current.GetType()));
             }
             this.collectionWriter.WriteItem(base.GetPropertyValue("element", propertyResourceType, current, false));
             hasMoved = elements.MoveNext();
         }
         this.collectionWriter.WriteEnd();
         this.collectionWriter.Flush();
     }
 }
Exemplo n.º 2
0
        /// <summary>
        /// Writes the given <paramref name="graph"/> using the given <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The <see cref="ODataCollectionWriter"/> to use.</param>
        /// <param name="graph">The collection to write.</param>
        /// <param name="collectionType">The EDM type of the collection.</param>
        /// <param name="writeContext">The serializer context.</param>
        public async Task WriteCollectionAsync(ODataCollectionWriter writer, object graph, IEdmTypeReference collectionType,
                                               ODataSerializerContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

            ODataCollectionStart collectionStart = GetCollectionStart(writeContext);

            await writer.WriteStartAsync(collectionStart);

            if (graph != null)
            {
                ODataCollectionValue collectionValue = CreateODataValue(graph, collectionType, writeContext) as ODataCollectionValue;
                if (collectionValue != null)
                {
                    foreach (object item in collectionValue.Items)
                    {
                        await writer.WriteItemAsync(item);
                    }
                }
            }

            await writer.WriteEndAsync();
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates an <see cref="ODataCollectionWriter"/> for the specified format and the specified version and
        /// invokes the specified methods on it. It then parses
        /// the written Xml/JSON and compares it to the expected result as specified in the descriptor.
        /// </summary>
        /// <param name="descriptor">The test descriptor to process.</param>
        /// <param name="testConfiguration">The configuration of the test.</param>
        /// <param name="assert">The assertion handler to report errors to.</param>
        /// <param name="baselineLogger">Logger to log baseline.</param>
        internal static void WriteAndVerifyCollectionPayload(CollectionWriterTestDescriptor descriptor, WriterTestConfiguration testConfiguration, AssertionHandler assert, BaselineLogger baselineLogger)
        {
            baselineLogger.LogConfiguration(testConfiguration);
            baselineLogger.LogModelPresence(descriptor.Model);

            // serialize to a memory stream
            using (var memoryStream = new MemoryStream())
                using (var testMemoryStream = new TestStream(memoryStream, ignoreDispose: true))
                {
                    TestMessage testMessage = null;
                    Exception   exception   = TestExceptionUtils.RunCatching(() =>
                    {
                        using (var messageWriter = TestWriterUtils.CreateMessageWriter(testMemoryStream, testConfiguration, assert, out testMessage, null, descriptor.Model))
                        {
                            IEdmTypeReference itemTypeReference = descriptor.ItemTypeParameter;
                            ODataCollectionWriter writer        = itemTypeReference == null
                            ? messageWriter.CreateODataCollectionWriter()
                            : messageWriter.CreateODataCollectionWriter(itemTypeReference);
                            WriteCollectionPayload(messageWriter, writer, true, descriptor);
                        }
                    });
                    exception = TestExceptionUtils.UnwrapAggregateException(exception, assert);

                    WriterTestExpectedResults expectedResults = descriptor.ExpectedResultCallback(testConfiguration);
                    TestWriterUtils.ValidateExceptionOrLogResult(testMessage, testConfiguration, expectedResults, exception, assert, descriptor.TestDescriptorSettings.ExpectedResultSettings.ExceptionVerifier, baselineLogger);
                    TestWriterUtils.ValidateContentType(testMessage, expectedResults, true, assert);
                }
        }
Exemplo n.º 4
0
        public static async Task WriteCollectionAsync(IEdmModel edmModel, ODataUri odataUri, IAsyncEnumerator <Object> asyncEnumerator, Stream responseStream)
        {
            var importSegment = (OperationImportSegment)odataUri.Path.LastSegment;
            IEdmOperationImport operationImport = importSegment.OperationImports.Single();
            Type returnType = edmModel.GetClrType(operationImport.Operation.ReturnType.Definition);

            IODataRequestMessage requestMessage = new Infrastructure.OeInMemoryMessage(responseStream, null);

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage,
                                                                             new ODataMessageWriterSettings()
            {
                EnableMessageStreamDisposal = false, ODataUri = odataUri
            }, edmModel))
            {
                IEdmTypeReference     typeRef = OeEdmClrHelper.GetEdmTypeReference(edmModel, returnType);
                ODataCollectionWriter writer  = await messageWriter.CreateODataCollectionWriterAsync(typeRef).ConfigureAwait(false);

                await writer.WriteStartAsync(new ODataCollectionStart()).ConfigureAwait(false);

                while (await asyncEnumerator.MoveNextAsync().ConfigureAwait(false))
                {
                    Object value = asyncEnumerator.Current;
                    if (value != null && value.GetType().IsEnum)
                    {
                        value = value.ToString();
                    }

                    await writer.WriteItemAsync(value).ConfigureAwait(false);
                }

                await writer.WriteEndAsync().ConfigureAwait(false);
            }
        }
Exemplo n.º 5
0
        /// <inheritdoc/>
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            ODataCollectionWriter writer = messageWriter.CreateODataCollectionWriter();

            writer.WriteStart(
                new ODataCollectionStart
            {
                Name = writeContext.ServiceOperationName
            });

            ODataProperty property = CreateProperty(graph, writeContext.ServiceOperationName, writeContext);

            if (property != null)
            {
                ODataCollectionValue collectionValue = property.Value as ODataCollectionValue;

                foreach (object item in collectionValue.Items)
                {
                    writer.WriteItem(item);
                }

                writer.WriteEnd();
                writer.Flush();
            }
        }
Exemplo n.º 6
0
        private void WriteParameters(ODataMessageWriterTestWrapper messageWriter, ODataParameters parameters, IEdmOperationImport functionImport)
        {
            ODataParameterWriter parameterWriter = messageWriter.CreateODataParameterWriter(functionImport);

            parameterWriter.WriteStart();
            foreach (var parameter in parameters)
            {
                ODataCollectionStart collectionStart = parameter.Value as ODataCollectionStart;
                ODataResourceSet     feed;
                ODataResource        entry;
                if (collectionStart != null)
                {
                    ODataCollectionWriter collectionWriter = parameterWriter.CreateCollectionWriter(parameter.Key);
                    this.WriteCollection(collectionWriter, collectionStart);
                    collectionWriter.Flush();
                }
                else if ((feed = parameter.Value as ODataResourceSet) != null)
                {
                    this.WriteFeed(parameterWriter.CreateResourceSetWriter(parameter.Key), feed);
                }
                else if ((entry = parameter.Value as ODataResource) != null)
                {
                    this.WriteEntry(parameterWriter.CreateResourceWriter(parameter.Key), entry);
                }
                else
                {
                    parameterWriter.WriteValue(parameter.Key, parameter.Value);
                }
            }

            parameterWriter.WriteEnd();
            parameterWriter.Flush();
        }
Exemplo n.º 7
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="collectionWriter">The writer to wrap.</param>
        /// <param name="testConfiguration">The test configuration to use.</param>
        public ODataCollectionWriterTestWrapper(ODataCollectionWriter collectionWriter, WriterTestConfiguration testConfiguration)
        {
            ExceptionUtilities.CheckArgumentNotNull(collectionWriter, "collectionWriter");
            ExceptionUtilities.CheckArgumentNotNull(testConfiguration, "testConfiguration");

            this.collectionWriter  = collectionWriter;
            this.testConfiguration = testConfiguration;
        }
Exemplo n.º 8
0
        private void WriteCollection(ODataMessageWriterTestWrapper messageWriter, ODataCollectionStart collection)
        {
            ODataCollectionWriter collectionWriter = messageWriter.CreateODataCollectionWriter();

            this.WriteCollection(collectionWriter, collection);

            collectionWriter.Flush();
        }
Exemplo n.º 9
0
        /// <summary>
        /// Writes the given <paramref name="graph"/> using the given <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The <see cref="ODataCollectionWriter"/> to use.</param>
        /// <param name="graph">The collection to write.</param>
        /// <param name="collectionType">The EDM type of the collection.</param>
        /// <param name="writeContext">The serializer context.</param>
        public void WriteCollection(ODataCollectionWriter writer, object graph, IEdmTypeReference collectionType,
                                    ODataSerializerContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

            ODataCollectionStart collectionStart = new ODataCollectionStart {
                Name = writeContext.RootElementName
            };

            if (writeContext.Request != null)
            {
                if (writeContext.Request.ODataProperties().NextLink != null)
                {
                    collectionStart.NextPageLink = writeContext.Request.ODataProperties().NextLink;
                }

                if (writeContext.Request.ODataProperties().TotalCount != null)
                {
                    collectionStart.Count = writeContext.Request.ODataProperties().TotalCount;
                }
            }

            bool doNotSerializeIfNull   = false;
            bool serializeAsEmptyIfNull = false;

            if (writeContext.Request != null)
            {
                var config = writeContext.Request.GetConfiguration();
                if (config != null)
                {
                    doNotSerializeIfNull   = config.GetDoNotSerializeNullCollections();
                    serializeAsEmptyIfNull = config.GetSerializeNullCollectionsAsEmpty();
                }
            }

            if (graph == null && doNotSerializeIfNull)
            {
                return;
            }
            writer.WriteStart(collectionStart);

            if (graph != null || !serializeAsEmptyIfNull)
            {
                ODataCollectionValue collectionValue = CreateODataValue(graph, collectionType, writeContext) as ODataCollectionValue;
                if (collectionValue != null)
                {
                    foreach (object item in collectionValue.Items)
                    {
                        writer.WriteItem(item);
                    }
                }
            }

            writer.WriteEnd();
        }
        /// <summary>
        /// Writes the given <paramref name="graph"/> using the given <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The <see cref="ODataCollectionWriter"/> to use.</param>
        /// <param name="graph">The collection to write.</param>
        /// <param name="collectionType">The EDM type of the collection.</param>
        /// <param name="writeContext">The serializer context.</param>
        public virtual void WriteCollection(ODataCollectionWriter writer, object graph, IEdmTypeReference collectionType,
                                            ODataSerializerContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull(nameof(writeContext));
            }

            ODataCollectionStart collectionStart = new ODataCollectionStart {
                Name = writeContext.RootElementName
            };

            if (writeContext.Request != null)
            {
                ODataFeature odataFeature = writeContext.Request.ODataFeature() as ODataFeature;
                if (odataFeature.NextLink != null)
                {
                    collectionStart.NextPageLink = odataFeature.NextLink;
                }
                else if (odataFeature.QueryOptions != null)
                {
                    // Collection serializer is called only for collection of primitive values - A null object will be supplied since it is a non-entity value
                    SkipTokenHandler skipTokenHandler = writeContext.QueryOptions.Context.GetSkipTokenHandler();
                    collectionStart.NextPageLink = skipTokenHandler.GenerateNextPageLink(new Uri(writeContext.Request.GetEncodedUrl()), odataFeature.PageSize, null, writeContext);
                }

                if (odataFeature.TotalCount != null)
                {
                    collectionStart.Count = odataFeature.TotalCount;
                }
            }

            writer.WriteStart(collectionStart);

            if (graph != null)
            {
                ODataCollectionValue collectionValue = CreateODataValue(graph, collectionType, writeContext) as ODataCollectionValue;
                if (collectionValue != null)
                {
                    foreach (object item in collectionValue.Items)
                    {
                        writer.WriteItem(item);
                    }
                }
            }

            writer.WriteEnd();
        }
Exemplo n.º 11
0
        /// <summary>Writes multiple top-level elements, possibly none.</summary>
        /// <param name="expanded">Expanded results for elements.</param>
        /// <param name="elements">Enumerator for elements to write.</param>
        protected override void WriteTopLevelElements(IExpandedResult expanded, QueryResultInfo elements)
        {
            Debug.Assert(
                !this.RequestDescription.IsSingleResult,
                "!this.RequestDescription.IsSingleResult -- otherwise WriteTopLevelElement should have been called");

            if (this.RequestDescription.LinkUri)
            {
                bool needPop = this.PushSegmentForRoot();
                this.WriteLinkCollection(elements);
                this.PopSegmentName(needPop);
            }
            else
            {
                MetadataProviderEdmModel model     = this.Service.Provider.GetMetadataProviderEdmModel();
                OperationWrapper         operation = this.RequestDescription.LastSegmentInfo.Operation;

                IEdmOperation edmOperation = model.GetRelatedOperation(operation);
                Debug.Assert(edmOperation != null, "edmOperation != null");

                IEdmCollectionTypeReference collectionType = (IEdmCollectionTypeReference)edmOperation.ReturnType;
                bool isJsonLightResponse = ContentTypeUtil.IsResponseMediaTypeJsonLight(this.Service, /*isEntryOrFeed*/ false);
                this.collectionWriter = this.writer.CreateODataCollectionWriter(isJsonLightResponse ? null : collectionType.ElementType());

                ODataCollectionStart collectionStart = new ODataCollectionStart {
                    Name = this.ComputeContainerName()
                };
                collectionStart.SetSerializationInfo(new ODataCollectionStartSerializationInfo {
                    CollectionTypeName = collectionType.FullName()
                });

                this.collectionWriter.WriteStart(collectionStart);
                while (elements.HasMoved)
                {
                    object       element      = elements.Current;
                    ResourceType resourceType = element == null ?
                                                this.RequestDescription.TargetResourceType : WebUtil.GetResourceType(this.Provider, element);
                    if (resourceType == null)
                    {
                        throw new InvalidOperationException(Microsoft.OData.Service.Strings.Serializer_UnsupportedTopLevelType(element.GetType()));
                    }

                    this.collectionWriter.WriteItem(this.GetPropertyValue(XmlConstants.XmlCollectionItemElementName, resourceType, element, false /*openProperty*/).FromODataValue());
                    elements.MoveNext();
                }

                this.collectionWriter.WriteEnd();
                this.collectionWriter.Flush();
            }
        }
Exemplo n.º 12
0
        private void WriteCollection(ODataCollectionWriter collectionWriter, ODataCollectionStart collection)
        {
            collectionWriter.WriteStart(collection);
            var annotation = collection.GetAnnotation <ODataCollectionItemsObjectModelAnnotation>();

            if (annotation != null)
            {
                foreach (var item in annotation)
                {
                    collectionWriter.WriteItem(item);
                }
            }

            collectionWriter.WriteEnd();
        }
Exemplo n.º 13
0
        /// <inheritdoc/>
        public override void WriteObject(object graph, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

            ODataCollectionWriter writer = messageWriter.CreateODataCollectionWriter(ElementType);

            WriteCollection(writer, graph, writeContext);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Writes the given <paramref name="graph"/> using the given <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The <see cref="ODataCollectionWriter"/> to use.</param>
        /// <param name="graph">The collection to write.</param>
        /// <param name="collectionType">The EDM type of the collection.</param>
        /// <param name="writeContext">The serializer context.</param>
        public virtual Task WriteCollectionAsync(ODataCollectionWriter writer, object graph, IEdmTypeReference collectionType,
                                                 ODataSerializerContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

            ODataCollectionStart collectionStart = new ODataCollectionStart {
                Name = writeContext.RootElementName
            };

            if (writeContext.Request != null)
            {
                if (writeContext.Context.ODataFeature().NextLink != null)
                {
                    collectionStart.NextPageLink = writeContext.Context.ODataFeature().NextLink;
                }

                if (writeContext.Context.ODataFeature().TotalCount != null)
                {
                    collectionStart.Count = writeContext.Context.ODataFeature().TotalCount;
                }
            }

            writer.WriteStart(collectionStart);
            if (graph != null)
            {
                ODataCollectionValue collectionValue = CreateODataValue(graph, collectionType, writeContext) as ODataCollectionValue;
                if (collectionValue != null)
                {
                    foreach (object item in collectionValue.Items)
                    {
                        writer.WriteItem(item);
                    }
                }
            }

            writer.WriteEnd();
            return(Task.FromResult(false));
        }
Exemplo n.º 15
0
        /// <summary>
        /// Writes the given <paramref name="graph"/> using the given <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The <see cref="ODataCollectionWriter"/> to use.</param>
        /// <param name="graph">The collection to write.</param>
        /// <param name="collectionType">The EDM type of the collection.</param>
        /// <param name="writeContext">The serializer context.</param>
        public void WriteCollection(ODataCollectionWriter writer, object graph, IEdmTypeReference collectionType,
                                    ODataSerializerContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

            ODataCollectionStart collectionStart = new ODataCollectionStart {
                Name = writeContext.RootElementName
            };

            if (writeContext.Request != null)
            {
                if (writeContext.Request.ODataProperties().NextLink != null)
                {
                    collectionStart.NextPageLink = writeContext.Request.ODataProperties().NextLink;
                }

                if (writeContext.Request.ODataProperties().TotalCount != null)
                {
                    collectionStart.Count = writeContext.Request.ODataProperties().TotalCount;
                }
            }

            writer.WriteStart(collectionStart);

            ODataCollectionValue collectionValue = CreateODataValue(graph, collectionType, writeContext) as ODataCollectionValue;

            if (collectionValue != null)
            {
                foreach (object item in collectionValue.Items)
                {
                    writer.WriteItem(item);
                }
            }

            writer.WriteEnd();
        }
        /// <inheritdoc/>
        public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter,
                                         ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull("messageWriter");
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }

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

            Contract.Assert(collectionType != null);

            IEdmTypeReference     elementType = GetElementType(collectionType);
            ODataCollectionWriter writer      = messageWriter.CreateODataCollectionWriter(elementType);

            WriteCollection(writer, graph, collectionType.AsCollection(), writeContext);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Writes the given <paramref name="graph"/> using the given <paramref name="writer"/>.
        /// </summary>
        /// <param name="writer">The <see cref="ODataCollectionWriter"/> to use.</param>
        /// <param name="graph">The collection to write.</param>
        /// <param name="writeContext">The serializer context.</param>
        public void WriteCollection(ODataCollectionWriter writer, object graph, ODataSerializerContext writeContext)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

            ODataCollectionValue collectionValue = CreateODataValue(graph, writeContext) as ODataCollectionValue;

            writer.WriteStart(new ODataCollectionStart {
                Name = writeContext.RootElementName
            });

            if (collectionValue != null)
            {
                foreach (object item in collectionValue.Items)
                {
                    writer.WriteItem(item);
                }
            }

            writer.WriteEnd();
        }
Exemplo n.º 18
0
        /// <inheritdoc/>
        public override async Task WriteObjectAsync(object graph, Type type, ODataMessageWriter messageWriter,
                                                    ODataSerializerContext writeContext)
        {
            if (messageWriter == null)
            {
                throw Error.ArgumentNull(nameof(messageWriter));
            }

            if (writeContext == null)
            {
                throw Error.ArgumentNull(nameof(writeContext));
            }

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

            Contract.Assert(collectionType != null);

            IEdmTypeReference     elementType = GetElementType(collectionType);
            ODataCollectionWriter writer      = await messageWriter.CreateODataCollectionWriterAsync(elementType)
                                                .ConfigureAwait(false);

            await WriteCollectionAsync(writer, graph, collectionType.AsCollection(), writeContext).ConfigureAwait(false);
        }
Exemplo n.º 19
0
        public void SyncAsyncMismatchTest()
        {
            // ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
            this.CombinatorialEngineProvider.RunCombinations(
                TestCalls,
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => !tc.IsRequest && tc.Format == ODataFormat.Atom),
                new bool[] { false, true },
                (testCall, testConfiguration, testSynchronousCall) =>
            {
                using (var memoryStream = new TestStream())
                    using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert))
                    {
                        ODataCollectionWriter collectionWriter  = messageWriter.CreateODataCollectionWriter();
                        ODataCollectionWriterTestWrapper writer = (ODataCollectionWriterTestWrapper)collectionWriter;

                        this.Assert.ExpectedException(
                            () =>
                        {
                            if (testSynchronousCall)
                            {
                                testCall.Sync(writer);
                            }
                            else
                            {
                                testCall.Async(writer);
                            }
                        },
                            testConfiguration.Synchronous == testSynchronousCall ?
                            null :
                            testSynchronousCall
                                    ? ODataExpectedExceptions.ODataException("ODataCollectionWriterCore_SyncCallOnAsyncWriter")
                                    : ODataExpectedExceptions.ODataException("ODataCollectionWriterCore_AsyncCallOnSyncWriter"),
                            this.ExceptionVerifier);
                    }
            });
        }
Exemplo n.º 20
0
        private string WriteAndVerifyCollection(StreamResponseMessage responseMessage, ODataCollectionWriter odataWriter,
                                                bool hasModel, string mimeType)
        {
            var collectionStart = new ODataCollectionStart()
            {
                Name = "BackupContactInfo", Count = 12, NextPageLink = new Uri("http://localhost")
            };

            if (!hasModel)
            {
                collectionStart.SetSerializationInfo(new ODataCollectionStartSerializationInfo()
                {
                    CollectionTypeName = "Collection(" + NameSpace + "ContactDetails)"
                });
            }

            odataWriter.WriteStart(collectionStart);
            odataWriter.WriteItem(WritePayloadHelper.CreatePrimaryContactODataComplexValue());
            odataWriter.WriteEnd();

            Stream stream = responseMessage.GetStream();

            if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
            {
                stream.Seek(0, SeekOrigin.Begin);
                var settings = new ODataMessageReaderSettings()
                {
                    BaseUri = this.ServiceUri
                };

                ODataMessageReader    messageReader = new ODataMessageReader(responseMessage, settings, WritePayloadHelper.Model);
                ODataCollectionReader reader        = messageReader.CreateODataCollectionReader(WritePayloadHelper.ContactDetailType);
                bool collectionRead = false;
                while (reader.Read())
                {
                    if (reader.State == ODataCollectionReaderState.CollectionEnd)
                    {
                        collectionRead = true;
                    }
                }

                Assert.IsTrue(collectionRead, "collectionRead");
                Assert.AreEqual(ODataCollectionReaderState.Completed, reader.State);
            }

            return(WritePayloadHelper.ReadStreamContent(stream));
        }
Exemplo n.º 21
0
        /// <summary>
        /// Writes the collection payload as specified in the <paramref name="testDescriptor"/>.
        /// </summary>
        /// <param name="messageWriter">The message writer.</param>
        /// <param name="writer">The writer to write to.</param>
        /// <param name="flush">True if the stream should be flush before returning; otherwise false.</param>
        /// <param name="testDescriptor">The test descriptor specifying the collection to write.</param>
        internal static void WriteCollectionPayload(ODataMessageWriterTestWrapper messageWriter, ODataCollectionWriter writer, bool flush, CollectionWriterTestDescriptor testDescriptor)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(testDescriptor != null, "testDescriptor != null");

            object[] payloadItems     = testDescriptor.PayloadItems;
            int      payloadItemIndex = 0;

            foreach (CollectionWriterTestDescriptor.WriterInvocations invocation in testDescriptor.Invocations)
            {
                switch (invocation)
                {
                case CollectionWriterTestDescriptor.WriterInvocations.StartCollection:
                    ODataCollectionStartSerializationInfo serInfo = null;
                    if (!string.IsNullOrEmpty(testDescriptor.CollectionTypeName))
                    {
                        serInfo = new ODataCollectionStartSerializationInfo();
                        serInfo.CollectionTypeName = testDescriptor.CollectionTypeName;
                    }

                    writer.WriteStart(new ODataCollectionStart {
                        Name = testDescriptor.CollectionName, SerializationInfo = serInfo
                    });
                    break;

                case CollectionWriterTestDescriptor.WriterInvocations.Item:
                    object payloadItem = payloadItems[payloadItemIndex];

                    ODataError error = payloadItem as ODataError;
                    if (error != null)
                    {
                        throw new InvalidOperationException("Expected payload item but found an error.");
                    }

                    writer.WriteItem(payloadItem);
                    payloadItemIndex++;
                    break;

                case CollectionWriterTestDescriptor.WriterInvocations.Error:
                    ODataAnnotatedError error2 = testDescriptor.PayloadItems[payloadItemIndex] as ODataAnnotatedError;
                    if (error2 == null)
                    {
                        throw new InvalidOperationException("Expected an error but found a payload item.");
                    }

                    messageWriter.WriteError(error2.Error, error2.IncludeDebugInformation);
                    payloadItemIndex++;
                    break;

                case CollectionWriterTestDescriptor.WriterInvocations.EndCollection:
                    writer.WriteEnd();
                    break;

                case CollectionWriterTestDescriptor.WriterInvocations.UserException:
                    throw new Exception("User code triggered an exception.");

                default:
                    break;
                }
            }

            if (flush)
            {
                writer.Flush();
            }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Writes the body operation parameters associated with a ServiceAction. For each BodyOperationParameter:
        /// 1. calls ODataPropertyConverter  to convert CLR object into ODataValue/primitive values.
        /// 2. then calls ODataParameterWriter to write the ODataValue/primitive values.
        /// </summary>
        /// <param name="operationParameters">The list of operation parameters to write.</param>
        /// <param name="requestMessage">The OData request message used to write the operation parameters.</param>
        internal void WriteBodyOperationParameters(List <BodyOperationParameter> operationParameters, ODataRequestMessageWrapper requestMessage)
        {
            Debug.Assert(requestMessage != null, "requestMessage != null");
            Debug.Assert(operationParameters != null, "operationParameters != null");
            Debug.Assert(operationParameters.Any(), "operationParameters.Any()");

            using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(requestMessage, this.requestInfo, true /*isParameterPayload*/))
            {
                ODataParameterWriter parameterWriter = messageWriter.CreateODataParameterWriter((IEdmOperation)null);
                parameterWriter.WriteStart();

                foreach (OperationParameter operationParameter in operationParameters)
                {
                    if (operationParameter.Value == null)
                    {
                        parameterWriter.WriteValue(operationParameter.Name, operationParameter.Value);
                    }
                    else
                    {
                        ClientEdmModel model   = this.requestInfo.Model;
                        IEdmType       edmType = model.GetOrCreateEdmType(operationParameter.Value.GetType());
                        Debug.Assert(edmType != null, "edmType != null");

                        switch (edmType.TypeKind)
                        {
                        case EdmTypeKind.Collection:
                        {
                            // TODO: just call ODataPropertyConverter.CreateODataCollection()
                            IEnumerator           enumerator           = ((ICollection)operationParameter.Value).GetEnumerator();
                            ODataCollectionWriter collectionWriter     = parameterWriter.CreateCollectionWriter(operationParameter.Name);
                            ODataCollectionStart  odataCollectionStart = new ODataCollectionStart();
                            collectionWriter.WriteStart(odataCollectionStart);

                            while (enumerator.MoveNext())
                            {
                                Object collectionItem = enumerator.Current;
                                if (collectionItem == null)
                                {
                                    throw new NotSupportedException(Strings.Serializer_NullCollectionParamterItemValue(operationParameter.Name));
                                }

                                IEdmType edmItemType = model.GetOrCreateEdmType(collectionItem.GetType());
                                Debug.Assert(edmItemType != null, "edmItemType != null");

                                switch (edmItemType.TypeKind)
                                {
                                case EdmTypeKind.Complex:
                                {
                                    Debug.Assert(model.GetClientTypeAnnotation(edmItemType).ElementType != null, "edmItemType.GetClientTypeAnnotation().ElementType != null");
                                    ODataComplexValue complexValue = this.propertyConverter.CreateODataComplexValue(
                                        model.GetClientTypeAnnotation(edmItemType).ElementType,
                                        collectionItem,
                                        null /*propertyName*/,
                                        false /*isCollectionItem*/,
                                        null /*visitedComplexTypeObjects*/);

                                    Debug.Assert(complexValue != null, "complexValue != null");
                                    collectionWriter.WriteItem(complexValue);
                                    break;
                                }

                                case EdmTypeKind.Primitive:
                                {
                                    object primitiveItemValue = ODataPropertyConverter.ConvertPrimitiveValueToRecognizedODataType(collectionItem, collectionItem.GetType());
                                    collectionWriter.WriteItem(primitiveItemValue);
                                    break;
                                }

                                case EdmTypeKind.Enum:
                                {
                                    ODataEnumValue enumTmp = this.propertyConverter.CreateODataEnumValue(
                                        model.GetClientTypeAnnotation(edmItemType).ElementType,
                                        collectionItem,
                                        false);
                                    collectionWriter.WriteItem(enumTmp);
                                    break;
                                }

                                default:

                                    // EdmTypeKind.Entity
                                    // EdmTypeKind.Row
                                    // EdmTypeKind.EntityReference
                                    throw new NotSupportedException(Strings.Serializer_InvalidCollectionParamterItemType(operationParameter.Name, edmItemType.TypeKind));
                                }
                            }

                            collectionWriter.WriteEnd();
                            collectionWriter.Flush();
                            break;
                        }

                        case EdmTypeKind.Complex:
                        {
                            Debug.Assert(model.GetClientTypeAnnotation(edmType).ElementType != null, "model.GetClientTypeAnnotation(edmType).ElementType != null");
                            ODataComplexValue complexValue = this.propertyConverter.CreateODataComplexValue(
                                model.GetClientTypeAnnotation(edmType).ElementType,
                                operationParameter.Value,
                                null /*propertyName*/,
                                false /*isCollectionItemType*/,
                                null /*visitedComplexTypeObjects*/);

                            Debug.Assert(complexValue != null, "complexValue != null");
                            parameterWriter.WriteValue(operationParameter.Name, complexValue);
                            break;
                        }

                        case EdmTypeKind.Primitive:
                            object primitiveValue = ODataPropertyConverter.ConvertPrimitiveValueToRecognizedODataType(operationParameter.Value, operationParameter.Value.GetType());
                            parameterWriter.WriteValue(operationParameter.Name, primitiveValue);
                            break;

                        case EdmTypeKind.Enum:
                            ODataEnumValue tmp = this.propertyConverter.CreateODataEnumValue(
                                model.GetClientTypeAnnotation(edmType).ElementType,
                                operationParameter.Value,
                                false);
                            parameterWriter.WriteValue(operationParameter.Name, tmp);

                            break;

                        default:
                            // EdmTypeKind.Entity
                            // EdmTypeKind.Row
                            // EdmTypeKind.EntityReference
                            throw new NotSupportedException(Strings.Serializer_InvalidParameterType(operationParameter.Name, edmType.TypeKind));
                        }
                    } // else
                }     // foreach

                parameterWriter.WriteEnd();
                parameterWriter.Flush();
            }
        }
Exemplo n.º 23
0
        public void CollectionWriterStatesTest()
        {
            var testCases = new CollectionWriterStatesTestDescriptor[]
            {
                new CollectionWriterStatesTestDescriptor {
                    DebugDescription = "Start",
                    Setup            = null,
                    ExpectedResults  = new Dictionary <CollectionWriterAction, string> {
                        { CollectionWriterAction.Start, null },
                        { CollectionWriterAction.Item, "Cannot transition from state 'Start' to state 'Item'. The only valid actions in state 'Start' are to write the collection or to write nothing at all." },
                        { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Start'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." },
                        { CollectionWriterAction.Error, null },
                    }
                },
                new CollectionWriterStatesTestDescriptor {
                    DebugDescription = "Collection",
                    Setup            = (mw, w, s) => {
                        w.WriteStart(new ODataCollectionStart {
                            Name = "foo"
                        });
                    },
                    ExpectedResults = new Dictionary <CollectionWriterAction, string> {
                        { CollectionWriterAction.Start, "Cannot transition from state 'Collection' to state 'Collection'. The only valid actions in state 'Collection' are to write an item or to write the end of the collection." },
                        { CollectionWriterAction.Item, null },
                        { CollectionWriterAction.End, null },
                        { CollectionWriterAction.Error, null },
                    }
                },
                new CollectionWriterStatesTestDescriptor {
                    DebugDescription = "Item",
                    Setup            = (mw, w, s) => {
                        w.WriteStart(new ODataCollectionStart {
                            Name = "foo"
                        });
                        w.WriteItem(42);
                    },
                    ExpectedResults = new Dictionary <CollectionWriterAction, string> {
                        { CollectionWriterAction.Start, "Cannot transition from state 'Item' to state 'Collection'. The only valid actions in state 'Item' are to write an item or the end of the collection." },
                        { CollectionWriterAction.Item, null },
                        { CollectionWriterAction.End, null },
                        { CollectionWriterAction.Error, null },
                    }
                },
                new CollectionWriterStatesTestDescriptor {
                    DebugDescription = "Completed",
                    Setup            = (mw, w, s) => {
                        w.WriteStart(new ODataCollectionStart {
                            Name = "foo"
                        });
                        w.WriteEnd();
                    },
                    ExpectedResults = new Dictionary <CollectionWriterAction, string> {
                        { CollectionWriterAction.Start, "Cannot transition from state 'Completed' to state 'Collection'. Nothing further can be written once the writer has completed." },
                        { CollectionWriterAction.Item, "Cannot transition from state 'Completed' to state 'Item'. Nothing further can be written once the writer has completed." },
                        { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Completed'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." },
                        { CollectionWriterAction.Error, "Cannot transition from state 'Completed' to state 'Error'. Nothing further can be written once the writer has completed." },
                    }
                },
                new CollectionWriterStatesTestDescriptor {
                    DebugDescription = "ODataExceptionThrown",
                    Setup            = (mw, w, s) => {
                        TestExceptionUtils.RunCatching(() => w.WriteItem(42));
                    },
                    ExpectedResults = new Dictionary <CollectionWriterAction, string> {
                        { CollectionWriterAction.Start, "Cannot transition from state 'Error' to state 'Collection'. Nothing can be written once the writer entered the error state." },
                        { CollectionWriterAction.Item, "Cannot transition from state 'Error' to state 'Item'. Nothing can be written once the writer entered the error state." },
                        { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Error'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." },
                        { CollectionWriterAction.Error, null },
                    }
                },
                new CollectionWriterStatesTestDescriptor {
                    DebugDescription = "FatalExceptionThrown",
                    Setup            = (mw, w, s) => {
                        // In JSON we can make the stream fail
                        s.FailNextCall = true;
                        w.WriteStart(new ODataCollectionStart {
                            Name = "foo"
                        });
                        TestExceptionUtils.RunCatching(() => w.Flush());
                    },
                    ExpectedResults = new Dictionary <CollectionWriterAction, string> {
                        { CollectionWriterAction.Start, "Cannot transition from state 'Error' to state 'Collection'. Nothing can be written once the writer entered the error state." },
                        { CollectionWriterAction.Item, "Cannot transition from state 'Error' to state 'Item'. Nothing can be written once the writer entered the error state." },
                        { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Error'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." },
                        { CollectionWriterAction.Error, null },
                    },
                    // There's no simple way to make the writer go into a fatal exception state with XmlWriter underneath.
                    // XmlWriter will move to an Error state if anything goes wrong with it, and thus we can't write into it anymore.
                    // As a result for example the in-stream error case for this one can't work as it should.
                    SkipForConfiguration = (tc) => tc.Format != ODataFormat.Json
                },
                new CollectionWriterStatesTestDescriptor {
                    DebugDescription = "Error",
                    Setup            = (mw, w, s) => {
                        mw.WriteError(new ODataError(), false);
                    },
                    ExpectedResults = new Dictionary <CollectionWriterAction, string> {
                        { CollectionWriterAction.Start, "Cannot transition from state 'Error' to state 'Collection'. Nothing can be written once the writer entered the error state." },
                        { CollectionWriterAction.Item, "Cannot transition from state 'Error' to state 'Item'. Nothing can be written once the writer entered the error state." },
                        { CollectionWriterAction.End, "ODataCollectionWriter.WriteEnd was called in an invalid state ('Error'); WriteEnd is only supported in states 'Start', 'Collection', and 'Item'." },
                        { CollectionWriterAction.Error, "The WriteError method or the WriteErrorAsync method on the ODataMessageWriter has already been called to write an error payload. Only a single error payload can be written with each ODataMessageWriter instance." },
                    }
                },
            };

            //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                EnumExtensionMethods.GetValues <CollectionWriterAction>().Cast <CollectionWriterAction>(),
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => false),
                (testCase, writerAction, testConfiguration) =>
            {
                using (TestStream stream = new TestStream())
                {
                    if (testCase.SkipForConfiguration != null && testCase.SkipForConfiguration(testConfiguration))
                    {
                        return;
                    }

                    // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will
                    // fail here because the writer is not left in a valid state.
                    var messageWriter            = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert);
                    ODataCollectionWriter writer = messageWriter.CreateODataCollectionWriter();
                    if (testCase.Setup != null)
                    {
                        testCase.Setup(messageWriter, writer, stream);
                    }

                    string expectedException = testCase.ExpectedResults[writerAction];

                    this.Assert.ExpectedException <ODataException>(
                        () => InvokeCollectionWriterAction(messageWriter, writer, writerAction),
                        expectedException);
                }
            });
        }
Exemplo n.º 24
0
        private void InvokeCollectionWriterAction(ODataMessageWriterTestWrapper messageWriter, ODataCollectionWriter writer, CollectionWriterAction writerAction)
        {
            switch (writerAction)
            {
            case CollectionWriterAction.Start:
                writer.WriteStart(new ODataCollectionStart {
                    Name = "foo"
                });
                break;

            case CollectionWriterAction.Item:
                writer.WriteItem(42);
                break;

            case CollectionWriterAction.End:
                writer.WriteEnd();
                break;

            case CollectionWriterAction.Error:
                messageWriter.WriteError(new ODataError(), false);
                break;
            }
        }
Exemplo n.º 25
0
        /// <summary>
        /// Writes collection value in body operation parameter.
        /// </summary>
        /// <param name="parameterWriter">The odata parameter writer.</param>
        /// <param name="operationParameter">The operation parameter.</param>
        /// <param name="edmCollectionType">The edm collection type.</param>
        private void WriteCollectionValueInBodyOperationParameter(ODataParameterWriter parameterWriter, BodyOperationParameter operationParameter, IEdmCollectionType edmCollectionType)
        {
            ClientEdmModel model = this.requestInfo.Model;

            var elementTypeKind = edmCollectionType.ElementType.TypeKind();

            if (elementTypeKind == EdmTypeKind.Entity || elementTypeKind == EdmTypeKind.Complex)
            {
                ODataWriter feedWriter = parameterWriter.CreateResourceSetWriter(operationParameter.Name);
                feedWriter.WriteStart(new ODataResourceSet());

                IEnumerator enumerator = ((ICollection)operationParameter.Value).GetEnumerator();

                while (enumerator.MoveNext())
                {
                    Object collectionItem = enumerator.Current;
                    if (collectionItem == null)
                    {
                        if (elementTypeKind == EdmTypeKind.Complex)
                        {
                            feedWriter.WriteStart((ODataResource)null);
                            feedWriter.WriteEnd();
                            continue;
                        }
                        else
                        {
                            throw new NotSupportedException(Strings.Serializer_NullCollectionParamterItemValue(operationParameter.Name));
                        }
                    }

                    IEdmType edmItemType = model.GetOrCreateEdmType(collectionItem.GetType());
                    Debug.Assert(edmItemType != null, "edmItemType != null");

                    if (edmItemType.TypeKind != EdmTypeKind.Entity && edmItemType.TypeKind != EdmTypeKind.Complex)
                    {
                        throw new NotSupportedException(Strings.Serializer_InvalidCollectionParamterItemType(operationParameter.Name, edmItemType.TypeKind));
                    }

                    Debug.Assert(model.GetClientTypeAnnotation(edmItemType).ElementType != null, "edmItemType.GetClientTypeAnnotation().ElementType != null");
                    ODataResourceWrapper entry = this.CreateODataResourceFromEntityOperationParameter(model.GetClientTypeAnnotation(edmItemType), collectionItem);
                    Debug.Assert(entry != null, "entry != null");
                    ODataWriterHelper.WriteResource(feedWriter, entry);
                }

                feedWriter.WriteEnd();
                feedWriter.Flush();
            }
            else
            {
                ODataCollectionWriter collectionWriter     = parameterWriter.CreateCollectionWriter(operationParameter.Name);
                ODataCollectionStart  odataCollectionStart = new ODataCollectionStart();
                collectionWriter.WriteStart(odataCollectionStart);

                IEnumerator enumerator = ((ICollection)operationParameter.Value).GetEnumerator();

                while (enumerator.MoveNext())
                {
                    Object collectionItem = enumerator.Current;
                    if (collectionItem == null)
                    {
                        collectionWriter.WriteItem(null);
                        continue;
                    }

                    IEdmType edmItemType = model.GetOrCreateEdmType(collectionItem.GetType());
                    Debug.Assert(edmItemType != null, "edmItemType != null");

                    switch (edmItemType.TypeKind)
                    {
                    case EdmTypeKind.Primitive:
                    {
                        object primitiveItemValue = ODataPropertyConverter.ConvertPrimitiveValueToRecognizedODataType(collectionItem, collectionItem.GetType());
                        collectionWriter.WriteItem(primitiveItemValue);
                        break;
                    }

                    case EdmTypeKind.Enum:
                    {
                        ODataEnumValue enumTmp = this.propertyConverter.CreateODataEnumValue(model.GetClientTypeAnnotation(edmItemType).ElementType, collectionItem, false);
                        collectionWriter.WriteItem(enumTmp);
                        break;
                    }

                    default:
                        // EdmTypeKind.Entity
                        // EdmTypeKind.Row
                        // EdmTypeKind.EntityReference
                        throw new NotSupportedException(Strings.Serializer_InvalidCollectionParamterItemType(operationParameter.Name, edmItemType.TypeKind));
                    }
                }

                collectionWriter.WriteEnd();
                collectionWriter.Flush();
            }
        }