public ODataJsonLightInheritComplexCollectionWriterTests()
        {
            collectionStartWithoutSerializationInfo = new ODataCollectionStart();

            collectionStartWithSerializationInfo = new ODataCollectionStart();
            collectionStartWithSerializationInfo.SetSerializationInfo(new ODataCollectionStartSerializationInfo { CollectionTypeName = "Collection(ns.Address)" });

            address = new ODataComplexValue { Properties = new[]
            {
                new ODataProperty { Name = "Street", Value = "1 Microsoft Way" }, 
                new ODataProperty { Name = "Zipcode", Value = 98052 }, 
                new ODataProperty { Name = "State", Value = new ODataEnumValue("WA", "ns.StateEnum") }, 
                new ODataProperty { Name = "City", Value = "Shanghai" }
            }, TypeName = "TestNamespace.DerivedAddress" };
            items = new[] { address };

            EdmComplexType addressType = new EdmComplexType("ns", "Address");
            addressType.AddProperty(new EdmStructuralProperty(addressType, "Street", EdmCoreModel.Instance.GetString(isNullable: true)));
            addressType.AddProperty(new EdmStructuralProperty(addressType, "Zipcode", EdmCoreModel.Instance.GetInt32(isNullable: true)));
            var stateEnumType = new EdmEnumType("ns", "StateEnum", isFlags: true);
            stateEnumType.AddMember("IL", new EdmIntegerConstant(1));
            stateEnumType.AddMember("WA", new EdmIntegerConstant(2));
            addressType.AddProperty(new EdmStructuralProperty(addressType, "State", new EdmEnumTypeReference(stateEnumType, true)));
            
            EdmComplexType derivedAddressType = new EdmComplexType("ns", "DerivedAddress", addressType, false);
            derivedAddressType.AddProperty(new EdmStructuralProperty(derivedAddressType, "City", EdmCoreModel.Instance.GetString(isNullable: true)));

            addressTypeReference = new EdmComplexTypeReference(addressType, isNullable: false);
            derivedAddressTypeReference = new EdmComplexTypeReference(derivedAddressType, isNullable: false);
        }
 public void ShouldBeAbleToClearTheCollectionStartSerializationInfo()
 {
     ODataCollectionStart collectionStart = new ODataCollectionStart();
     ODataCollectionStartSerializationInfo serializationInfo = new ODataCollectionStartSerializationInfo { CollectionTypeName = "Collection(Edm.String)" };
     collectionStart.SerializationInfo = serializationInfo;
     collectionStart.SetSerializationInfo(null);
     collectionStart.SerializationInfo.Should().BeNull();
 }
 public void ShouldBeAbleToSetTheCollectionStartSerializationInfo()
 {
     ODataCollectionStart collectionStart = new ODataCollectionStart();
     ODataCollectionStartSerializationInfo serializationInfo = new ODataCollectionStartSerializationInfo { CollectionTypeName = "Collection(Edm.String)" };
     collectionStart.SetSerializationInfo(serializationInfo);
     collectionStart.SerializationInfo.Should().BeSameAs(serializationInfo);
 }
        public void FlagsEnumAsCollectionItemAsTopLevelValue_StrAsValue_StrAsTypeName_MinimalMetadata_CollecionWriter()
        {
            ODataCollectionStart collectionStart = new ODataCollectionStart();
            collectionStart.SetSerializationInfo(new ODataCollectionStartSerializationInfo { CollectionTypeName = "Collection(NS.ColorFlags)" });
            ODataEnumValue[] items = new ODataEnumValue[] 
            {
                new ODataEnumValue(ColorFlags.Red.ToString(), "NS.ColorFlags"),
                new ODataEnumValue(null, "NS.ColorFlags_Undefined"),
                new ODataEnumValue("Red,Green", "NS.ColorFlags"),
                new ODataEnumValue("Red|Green", "NS.ColorFlags"),
                new ODataEnumValue(ColorFlags.Green.ToString(), "NS.ColorFlags")
            };

            EdmEnumTypeReference enumRef = new EdmEnumTypeReference((IEdmEnumType)this.userModel.FindType("NS.ColorFlags"), true);
            WriteToMessageWriterAndVerifyPayload(
                contentType: "application/json;odata.metadata=minimal;",
                writerAction: (writer) =>
                {
                    ODataCollectionWriter collectionWriter = writer.CreateODataCollectionWriter(enumRef);
                    collectionWriter.WriteStart(collectionStart);
                    foreach (object item in items)
                    {
                        collectionWriter.WriteItem(item);
                    }

                    collectionWriter.WriteEnd();
                },
                expectedPayload: "{\"@odata.context\":\"http://odata.org/test/$metadata#Collection(NS.ColorFlags)\",\"value\":[\"Red\",null,\"Red,Green\",\"Red|Green\",\"Green\"]}"
            );
        }
 public void ShouldWriteContextUriBasedOnSerializationInfoForComplexCollectionRequestWithoutUserModelWhenBothItemTypeAndSerializationInfoAreGiven()
 {
     ODataCollectionStart collectionStart = new ODataCollectionStart();
     collectionStart.SetSerializationInfo(new ODataCollectionStartSerializationInfo { CollectionTypeName = "Collection(foo.bar)" });
     WriteAndValidate(collectionStart, this.items, "{\"@odata.context\":\"http://odata.org/test/$metadata#Collection(foo.bar)\",\"value\":[{\"Street\":\"1 Microsoft Way\",\"Zipcode\":98052,\"State\":\"WA\"}]}", writingResponse: false, itemTypeReference: this.addressTypeReference);
 }
 public void ShouldWriteCountAndNextLinkAnnotationOfComplexCollectionPropertyIfSpecified()
 {
     ODataCollectionStart collectionStart = new ODataCollectionStart()
     {
         Count = 3,
         NextPageLink = new Uri("http://next-link")
     };
     collectionStart.SetSerializationInfo(new ODataCollectionStartSerializationInfo { CollectionTypeName = "Collection(foo.bar)" });
     WriteAndValidate(collectionStart, this.items, "{\"@odata.context\":\"http://odata.org/test/$metadata#Collection(foo.bar)\",\"@odata.count\":3,\"@odata.nextLink\":\"http://next-link/\",\"value\":[{\"Street\":\"1 Microsoft Way\",\"Zipcode\":98052,\"State\":\"WA\"}]}", writingResponse: true, itemTypeReference: this.addressTypeReference);
 }
        /// <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();
            }
        }
        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);
        }