public void CanSerializerSingleton() { // Arrange const string expect = "{" + "\"@odata.context\":\"http://localhost/odata/$metadata#Boss\"," + "\"@odata.id\":\"http://localhost/odata/Boss\"," + "\"@odata.editLink\":\"http://localhost/odata/Boss\"," + "\"EmployeeId\":987,\"EmployeeName\":\"John Mountain\"}"; IEdmModel model = GetEdmModel(); IEdmSingleton singleton = model.EntityContainer.FindSingleton("Boss"); HttpRequestMessage request = GetRequest(model, singleton); ODataSerializerContext readContext = new ODataSerializerContext() { Url = new UrlHelper(request), Path = request.ODataProperties().Path, Model = model, NavigationSource = singleton }; ODataSerializerProvider serializerProvider = new DefaultODataSerializerProvider(); EmployeeModel boss = new EmployeeModel {EmployeeId = 987, EmployeeName = "John Mountain"}; MemoryStream bufferedStream = new MemoryStream(); // Act ODataEntityTypeSerializer serializer = new ODataEntityTypeSerializer(serializerProvider); serializer.WriteObject(boss, typeof(EmployeeModel), GetODataMessageWriter(model, bufferedStream), readContext); // Assert string result = Encoding.UTF8.GetString(bufferedStream.ToArray()); Assert.Equal(expect, result); }
/// <summary> /// Initializes a new instance of the <see cref="DefaultODataSerializerProvider"/> class. /// </summary> public DefaultODataSerializerProvider() { _feedSerializer = new ODataFeedSerializer(this); _collectionSerializer = new ODataCollectionSerializer(this); _complexTypeSerializer = new ODataComplexTypeSerializer(this); _entityTypeSerializer = new ODataEntityTypeSerializer(this); }
/// <summary> /// Initializes a new instance of the <see cref="DefaultODataSerializerProvider"/> class. /// </summary> public DefaultODataSerializerProvider() { _feedSerializer = new ODataFeedSerializer(this); _collectionSerializer = new ODataCollectionSerializer(this); _complexTypeSerializer = new ODataComplexTypeSerializer(this); _entityTypeSerializer = new ODataEntityTypeSerializer(this); }
public ODataEntityTypeSerializerTests() { _model = SerializationTestsHelpers.SimpleCustomerOrderModel(); _model.SetAnnotationValue<ClrTypeAnnotation>(_model.FindType("Default.Customer"), new ClrTypeAnnotation(typeof(Customer))); _model.SetAnnotationValue<ClrTypeAnnotation>(_model.FindType("Default.Order"), new ClrTypeAnnotation(typeof(Order))); _customerSet = _model.FindDeclaredEntityContainer("Default.Container").FindEntitySet("Customers"); _customer = new Customer() { FirstName = "Foo", LastName = "Bar", ID = 10, }; _serializerProvider = new DefaultODataSerializerProvider(); _customerType = _model.GetEdmTypeReference(typeof(Customer)).AsEntity(); _serializer = new ODataEntityTypeSerializer(_serializerProvider); _path = new ODataPath(new EntitySetPathSegment(_customerSet)); _writeContext = new ODataSerializerContext() { EntitySet = _customerSet, Model = _model, Path = _path }; _entityInstanceContext = new EntityInstanceContext(_writeContext, _customerSet.ElementType.AsReference(), _customer); }
public void CreateStructuralProperty_Calls_CreateODataValueOnInnerSerializer() { // Arrange Mock<IEdmTypeReference> propertyType = new Mock<IEdmTypeReference>(); propertyType.Setup(t => t.Definition).Returns(new EdmEntityType("Namespace", "Name")); Mock<IEdmStructuralProperty> property = new Mock<IEdmStructuralProperty>(); property.Setup(p => p.Name).Returns("PropertyName"); Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(MockBehavior.Strict); var entity = new { PropertyName = 42 }; Mock<ODataEdmTypeSerializer> innerSerializer = new Mock<ODataEdmTypeSerializer>(ODataPayloadKind.Property); ODataValue propertyValue = new Mock<ODataValue>().Object; property.Setup(p => p.Type).Returns(propertyType.Object); serializerProvider.Setup(s => s.GetEdmTypeSerializer(propertyType.Object)).Returns(innerSerializer.Object); innerSerializer.Setup(s => s.CreateODataValue(42, propertyType.Object, _writeContext)).Returns(propertyValue).Verifiable(); var serializer = new ODataEntityTypeSerializer(serializerProvider.Object); EntityInstanceContext entityInstanceContext = new EntityInstanceContext(_writeContext, _customerType, entity); // Act ODataProperty createdProperty = serializer.CreateStructuralProperty(property.Object, entityInstanceContext); // Assert innerSerializer.Verify(); Assert.Equal("PropertyName", createdProperty.Name); Assert.Equal(propertyValue, createdProperty.Value); }
public void CreateStructuralProperty_ThrowsSerializationException_TypeCannotBeSerialized() { // Arrange Mock<IEdmTypeReference> propertyType = new Mock<IEdmTypeReference>(); propertyType.Setup(t => t.Definition).Returns(new EdmEntityType("Namespace", "Name")); Mock<IEdmStructuralProperty> property = new Mock<IEdmStructuralProperty>(); Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(MockBehavior.Strict); IEdmEntityObject entity = new Mock<IEdmEntityObject>().Object; property.Setup(p => p.Type).Returns(propertyType.Object); serializerProvider.Setup(s => s.GetEdmTypeSerializer(propertyType.Object)).Returns<ODataEdmTypeSerializer>(null); var serializer = new ODataEntityTypeSerializer(serializerProvider.Object); // Act & Assert Assert.Throws<SerializationException>( () => serializer.CreateStructuralProperty(property.Object, new EntityInstanceContext { EdmObject = entity }), "'Namespace.Name' cannot be serialized using the ODataMediaTypeFormatter."); }
private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataDeltaWriter writer, ODataSerializerContext writeContext) { Contract.Assert(writer != null); Contract.Assert(writeContext != null); Contract.Assert(enumerable != null); Contract.Assert(feedType != null); ODataDeltaFeed deltaFeed = CreateODataDeltaFeed(enumerable, feedType.AsCollection(), writeContext); if (deltaFeed == null) { throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed)); } // save this for later to support JSON odata.streaming. Uri nextPageLink = deltaFeed.NextPageLink; deltaFeed.NextPageLink = null; //Start writing of the Delta Feed writer.WriteStart(deltaFeed); //Iterate over all the entries present and select the appropriate write method. //Write method creates ODataDeltaDeletedEntry / ODataDeltaDeletedLink / ODataDeltaLink or ODataEntry. foreach (object entry in enumerable) { if (entry == null) { throw new SerializationException(SRResources.NullElementInCollection); } IEdmChangedObject edmChangedObject = entry as IEdmChangedObject; if (edmChangedObject == null) { throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName)); } switch (edmChangedObject.DeltaKind) { case EdmDeltaEntityKind.DeletedEntry: WriteDeltaDeletedEntry(entry, writer, writeContext); break; case EdmDeltaEntityKind.DeletedLinkEntry: WriteDeltaDeletedLink(entry, writer, writeContext); break; case EdmDeltaEntityKind.LinkEntry: WriteDeltaLink(entry, writer, writeContext); break; case EdmDeltaEntityKind.Entry: { IEdmEntityTypeReference elementType = GetEntityType(feedType); ODataEntityTypeSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataEntityTypeSerializer; if (entrySerializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name)); } entrySerializer.WriteDeltaObjectInline(entry, elementType, writer, writeContext); break; } default: break; } } // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(feed), // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed // object before calling WriteEnd(), the next page link will be written at the end, as required for // odata.streaming=true support. if (nextPageLink != null) { deltaFeed.NextPageLink = nextPageLink; } //End Writing of the Delta Feed writer.WriteEnd(); }
public virtual ODataOperation CreateODataOperation(IEdmOperation operation, FeedContext feedContext, ODataSerializerContext writeContext) { if (operation == null) { throw Error.ArgumentNull("operation"); } if (feedContext == null) { throw Error.ArgumentNull("feedContext"); } if (writeContext == null) { throw Error.ArgumentNull("writeContext"); } ODataMetadataLevel metadataLevel = writeContext.MetadataLevel; IEdmModel model = writeContext.Model; if (metadataLevel != ODataMetadataLevel.FullMetadata) { return(null); } ProcedureLinkBuilder builder; IEdmAction action = operation as IEdmAction; if (action != null) { builder = model.GetActionLinkBuilder(action); } else { builder = model.GetFunctionLinkBuilder((IEdmFunction)operation); } if (builder == null) { return(null); } Uri target = builder.BuildLink(feedContext); if (target == null) { return(null); } Uri baseUri = new Uri(writeContext.Url.CreateODataLink(new MetadataPathSegment())); Uri metadata = new Uri(baseUri, "#" + operation.FullName()); ODataOperation odataOperation; if (action != null) { odataOperation = new ODataAction(); } else { odataOperation = new ODataFunction(); } odataOperation.Metadata = metadata; // Always omit the title in minimal/no metadata modes. ODataEntityTypeSerializer.EmitTitle(model, operation, odataOperation); // Omit the target in minimal/no metadata modes unless it doesn't follow conventions. if (metadataLevel == ODataMetadataLevel.FullMetadata || !builder.FollowsConventions) { odataOperation.Target = target; } return(odataOperation); }
public void CreateEntry_Works_ToAppendDynamicProperties_ForOpenEntityType() { // Arrange IEdmModel model = SerializationTestsHelpers.SimpleOpenTypeModel(); IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers"); IEdmEntityType customerType = model.FindDeclaredType("Default.Customer") as IEdmEntityType; Type simpleOpenCustomer = typeof(SimpleOpenCustomer); model.SetAnnotationValue(customerType, new ClrTypeAnnotation(simpleOpenCustomer)); IEdmComplexType addressType = model.FindDeclaredType("Default.Address") as IEdmComplexType; Type simpleOpenAddress = typeof(SimpleOpenAddress); model.SetAnnotationValue(addressType, new ClrTypeAnnotation(simpleOpenAddress)); IEdmEnumType enumType = model.FindDeclaredType("Default.SimpleEnum") as IEdmEnumType; Type simpleEnumType = typeof(SimpleEnum); model.SetAnnotationValue(enumType, new ClrTypeAnnotation(simpleEnumType)); model.SetAnnotationValue(customerType, new DynamicPropertyDictionaryAnnotation( simpleOpenCustomer.GetProperty("CustomerProperties"))); model.SetAnnotationValue(addressType, new DynamicPropertyDictionaryAnnotation( simpleOpenAddress.GetProperty("Properties"))); ODataSerializerProvider serializerProvider = new DefaultODataSerializerProvider(); ODataEntityTypeSerializer serializer = new ODataEntityTypeSerializer(serializerProvider); SelectExpandNode selectExpandNode = new SelectExpandNode(null, customerType, model); ODataSerializerContext writeContext = new ODataSerializerContext { Model = model, Path = new ODataPath(new EntitySetPathSegment(customers)) }; SimpleOpenCustomer customer = new SimpleOpenCustomer() { CustomerId = 991, Name = "Name #991", Address = new SimpleOpenAddress { City = "a city", Street = "a street", Properties = new Dictionary<string, object> { {"ArrayProperty", new[] { "15", "14", "13" } } } }, CustomerProperties = new Dictionary<string, object>() }; customer.CustomerProperties.Add("EnumProperty", SimpleEnum.Fourth); customer.CustomerProperties.Add("GuidProperty", new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA")); customer.CustomerProperties.Add("ListProperty", new List<int>{5,4,3,2,1}); customer.CustomerProperties.Add("DateTimeProperty", new DateTime(2014, 10, 24)); EntityInstanceContext entityInstanceContext = new EntityInstanceContext(writeContext, customerType.ToEdmTypeReference(false) as IEdmEntityTypeReference, customer); // Act ODataEntry entry = serializer.CreateEntry(selectExpandNode, entityInstanceContext); // Assert Assert.Equal(entry.TypeName, "Default.Customer"); Assert.Equal(7, entry.Properties.Count()); // Verify the declared properties ODataProperty street = Assert.Single(entry.Properties.Where(p => p.Name == "CustomerId")); Assert.Equal(991, street.Value); ODataProperty city = Assert.Single(entry.Properties.Where(p => p.Name == "Name")); Assert.Equal("Name #991", city.Value); // Verify the nested open complex property ODataProperty address = Assert.Single(entry.Properties.Where(p => p.Name == "Address")); ODataComplexValue addressComplexValue = Assert.IsType<ODataComplexValue>(address.Value); ODataProperty addressDynamicProperty = Assert.Single(addressComplexValue.Properties.Where(p => p.Name == "ArrayProperty")); ODataCollectionValue addressCollectionValue = Assert.IsType<ODataCollectionValue>(addressDynamicProperty.Value); Assert.Equal(new[] { "15", "14", "13" }, addressCollectionValue.Items.OfType<string>().ToList()); Assert.Equal("Collection(Edm.String)", addressCollectionValue.TypeName); // Verify the dynamic properties ODataProperty enumProperty = Assert.Single(entry.Properties.Where(p => p.Name == "EnumProperty")); ODataEnumValue enumValue = Assert.IsType<ODataEnumValue>(enumProperty.Value); Assert.Equal("Fourth", enumValue.Value); Assert.Equal("Default.SimpleEnum", enumValue.TypeName); ODataProperty guidProperty = Assert.Single(entry.Properties.Where(p => p.Name == "GuidProperty")); Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), guidProperty.Value); ODataProperty listProperty = Assert.Single(entry.Properties.Where(p => p.Name == "ListProperty")); ODataCollectionValue collectionValue = Assert.IsType<ODataCollectionValue>(listProperty.Value); Assert.Equal(new List<int>{5,4,3,2,1}, collectionValue.Items.OfType<int>().ToList()); Assert.Equal("Collection(Edm.Int32)", collectionValue.TypeName); ODataProperty dateTimeProperty = Assert.Single(entry.Properties.Where(p => p.Name == "DateTimeProperty")); Assert.Equal(new DateTimeOffset(new DateTime(2014, 10, 24)), dateTimeProperty.Value); }
public void CreateEntry_Works_ToAppendNullDynamicProperties_ForOpenEntityType(bool enableNullDynamicProperty, int count) { // Arrange IEdmModel model = SerializationTestsHelpers.SimpleOpenTypeModel(); IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers"); IEdmEntityType customerType = model.FindDeclaredType("Default.Customer") as IEdmEntityType; Type simpleOpenCustomer = typeof(SimpleOpenCustomer); model.SetAnnotationValue(customerType, new ClrTypeAnnotation(simpleOpenCustomer)); IEdmComplexType addressType = model.FindDeclaredType("Default.Address") as IEdmComplexType; Type simpleOpenAddress = typeof(SimpleOpenAddress); model.SetAnnotationValue(addressType, new ClrTypeAnnotation(simpleOpenAddress)); IEdmEnumType enumType = model.FindDeclaredType("Default.SimpleEnum") as IEdmEnumType; Type simpleEnumType = typeof(SimpleEnum); model.SetAnnotationValue(enumType, new ClrTypeAnnotation(simpleEnumType)); model.SetAnnotationValue(customerType, new DynamicPropertyDictionaryAnnotation( simpleOpenCustomer.GetProperty("CustomerProperties"))); model.SetAnnotationValue(addressType, new DynamicPropertyDictionaryAnnotation( simpleOpenAddress.GetProperty("Properties"))); ODataSerializerProvider serializerProvider = new DefaultODataSerializerProvider(); ODataEntityTypeSerializer serializer = new ODataEntityTypeSerializer(serializerProvider); HttpConfiguration config = new HttpConfiguration(); config.SetSerializeNullDynamicProperty(enableNullDynamicProperty); HttpRequestMessage request = new HttpRequestMessage(); request.SetConfiguration(config); SelectExpandNode selectExpandNode = new SelectExpandNode(null, customerType, model); ODataSerializerContext writeContext = new ODataSerializerContext { Model = model, Path = new ODataPath(new EntitySetPathSegment(customers)), Request = request }; SimpleOpenCustomer customer = new SimpleOpenCustomer() { CustomerId = 991, Name = "Name #991", Address = new SimpleOpenAddress { City = "a city", Street = "a street", Properties = new Dictionary<string, object> { { "ArrayProperty", new[] { "15", "14", "13" } } } }, CustomerProperties = new Dictionary<string, object>() }; customer.CustomerProperties.Add("GuidProperty", new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA")); customer.CustomerProperties.Add("NullProperty", null); EntityInstanceContext entityInstanceContext = new EntityInstanceContext(writeContext, customerType.ToEdmTypeReference(false) as IEdmEntityTypeReference, customer); // Act ODataEntry entry = serializer.CreateEntry(selectExpandNode, entityInstanceContext); // Assert Assert.Equal(entry.TypeName, "Default.Customer"); Assert.Equal(count, entry.Properties.Count()); // Verify the declared properties ODataProperty street = Assert.Single(entry.Properties.Where(p => p.Name == "CustomerId")); Assert.Equal(991, street.Value); ODataProperty city = Assert.Single(entry.Properties.Where(p => p.Name == "Name")); Assert.Equal("Name #991", city.Value); // Verify the nested open complex property ODataProperty address = Assert.Single(entry.Properties.Where(p => p.Name == "Address")); ODataComplexValue addressComplexValue = Assert.IsType<ODataComplexValue>(address.Value); ODataProperty addressDynamicProperty = Assert.Single(addressComplexValue.Properties.Where(p => p.Name == "ArrayProperty")); ODataCollectionValue addressCollectionValue = Assert.IsType<ODataCollectionValue>(addressDynamicProperty.Value); Assert.Equal(new[] { "15", "14", "13" }, addressCollectionValue.Items.OfType<string>().ToList()); Assert.Equal("Collection(Edm.String)", addressCollectionValue.TypeName); // Verify the dynamic properties ODataProperty guidProperty = Assert.Single(entry.Properties.Where(p => p.Name == "GuidProperty")); Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), guidProperty.Value); ODataProperty nullProperty = entry.Properties.SingleOrDefault(p => p.Name == "NullProperty"); if (enableNullDynamicProperty) { Assert.NotNull(nullProperty); Assert.Null(nullProperty.Value); } else { Assert.Null(nullProperty); } }