public void NullPropertyTypeNameTest() { Version[] versions = new Version[] { null, new Version(4, 0), }; var innerComplexType = new EdmComplexType("TestNS", "ComplexType"); innerComplexType.AddStructuralProperty("NumberProperty", EdmCoreModel.Instance.GetInt32(true)); innerComplexType.AddStructuralProperty("StringProperty", EdmCoreModel.Instance.GetString(true)); var outerComplexType = new EdmComplexType("TestNS", "ComplexType"); outerComplexType.AddStructuralProperty("NumberProperty", EdmCoreModel.Instance.GetInt32(true)); outerComplexType.AddStructuralProperty("StringProperty", EdmCoreModel.Instance.GetString(true)); outerComplexType.AddStructuralProperty("InnerComplex", new EdmComplexTypeReference(innerComplexType, true)); var model = new EdmModel(); var complexType = new EdmComplexType("TestNS", "ComplexType"); complexType.AddStructuralProperty("NumberProperty", EdmCoreModel.Instance.GetInt32(true)); complexType.AddStructuralProperty("StringProperty", EdmCoreModel.Instance.GetString(true)); complexType.AddStructuralProperty("InnerComplex", new EdmComplexTypeReference(innerComplexType, true)); model.AddElement(complexType); var entityType = new EdmEntityType("TestNS", "EntityType", null, false, true); entityType.AddStructuralProperty("NumberProperty", EdmCoreModel.Instance.GetInt32(true)); entityType.AddStructuralProperty("StringProperty", EdmCoreModel.Instance.GetString(true)); entityType.AddStructuralProperty("ComplexProperty", new EdmComplexTypeReference(outerComplexType, true)); model.AddElement(entityType); var container = new EdmEntityContainer("TestNS", "DefaultContainer"); model.AddElement(container); var testDescriptorSet = versions.SelectMany(dataServiceVersion => versions.SelectMany(edmVersion => { model.SetEdmVersion(edmVersion); // Client only writes type for primitive properties with null value, Server writes it for both primitive and complex. // Edm.String is never written as the default is Edm.String. var testCases = new[] { new { PropertyName = "NumberProperty", ExpectedServerTypeName = "Edm.Int32", ExpectedClientTypeName = "Edm.Int32" }, new { PropertyName = "StringProperty", ExpectedServerTypeName = (string)null, ExpectedClientTypeName = (string)null }, new { PropertyName = "ComplexProperty", ExpectedServerTypeName = "TestNS.ComplexType", ExpectedClientTypeName = (string)null }, new { PropertyName = "OpenProperty", ExpectedServerTypeName = (string)null, ExpectedClientTypeName = (string)null }, new { PropertyName = "OpenProperty", ExpectedServerTypeName = (string)null, ExpectedClientTypeName = (string)null }, new { PropertyName = "ComplexProperty/NumberProperty", ExpectedServerTypeName = "Edm.Int32", ExpectedClientTypeName = "Edm.Int32" }, new { PropertyName = "ComplexProperty/StringProperty", ExpectedServerTypeName = (string)null, ExpectedClientTypeName = (string)null }, new { PropertyName = "ComplexProperty/InnerComplex", ExpectedServerTypeName = "TestNS.ComplexType", ExpectedClientTypeName = (string)null }, new { PropertyName = "ComplexProperty/InnerComplex/NumberProperty", ExpectedServerTypeName = "Edm.Int32", ExpectedClientTypeName = "Edm.Int32" }, new { PropertyName = "ComplexProperty/InnerComplex/StringProperty", ExpectedServerTypeName = (string)null, ExpectedClientTypeName = (string)null }, }; return testCases.Select(testCase => { string[] propertyPath = testCase.PropertyName.Split('/'); ODataProperty property = new ODataProperty { Name = propertyPath[propertyPath.Length - 1], Value = null }; for (int i = propertyPath.Length - 2; i >= 0; i--) { property = new ODataProperty { Name = propertyPath[i], Value = new ODataComplexValue { Properties = new[] { property } } }; } Func<XElement, XElement> extractor = (result) => { result = TestAtomUtils.ExtractPropertiesFromEntry(result); foreach (string name in propertyPath) { result = result.Element(TestAtomConstants.ODataXNamespace + name); } return result; }; return new Func<TestODataBehaviorKind, ODataVersion, PayloadWriterTestDescriptor<ODataItem>>( (behaviorKind, version) => { string expectedTypeName = null; switch (behaviorKind) { case TestODataBehaviorKind.Default: break; case TestODataBehaviorKind.WcfDataServicesClient: expectedTypeName = testCase.ExpectedClientTypeName; break; case TestODataBehaviorKind.WcfDataServicesServer: expectedTypeName = testCase.ExpectedServerTypeName; break; } // Starting with V3, we only support the standard behavior expectedTypeName = null; return new PayloadWriterTestDescriptor<ODataItem>( this.Settings, new ODataEntry() { TypeName = "TestNS.EntityType", Properties = new[] { property }, SerializationInfo = new ODataFeedAndEntrySerializationInfo() { NavigationSourceEntityTypeName = "TestNS.EntityType", NavigationSourceName = "MySet", ExpectedTypeName = "TestNS.EntityType" } }, (tc) => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = expectedTypeName == null ? "<type/>" : "<type>" + expectedTypeName + "</type>", FragmentExtractor = (result) => new XElement("type", (string)extractor(result).Attribute(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomTypeAttributeName)) } ) { Model = model }; }); }); })); this.CombinatorialEngineProvider.RunCombinations( TestWriterUtils.ODataBehaviorKinds, testDescriptorSet, this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent, (behaviorKind, testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.CloneAndApplyBehavior(behaviorKind); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor(behaviorKind, testConfiguration.Version), testConfiguration, this.Assert, this.Logger); }); }