Skip to content

Commit

Permalink
port from pr944 kosinsky:users/kokosins/IgnoreNullValuesV7, commit b2…
Browse files Browse the repository at this point in the history
  • Loading branch information
biaol-odata committed Feb 7, 2018
1 parent 590983b commit 2de403d
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ private void WriteNullProperty(
// TODO: Enable updating top-level properties to null #645
throw new ODataException("A null top-level property is not allowed to be serialized.");
}
else
else if (!this.MessageWriterSettings.IgnoreNullValues)
{
this.JsonWriter.WriteName(property.Name);
this.JsonLightValueSerializer.WriteNullValue();
Expand Down
9 changes: 9 additions & 0 deletions src/Microsoft.OData.Core/ODataMessageWriterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ public ODataUri ODataUri
/// </summary>
internal bool ThrowOnDuplicatePropertyNames { get; private set; }

/// <summary>
/// Don't serialize null values
/// </summary>
/// <remarks>
/// Default valus is false, that means serialize null values.
/// </remarks>
public bool IgnoreNullValues { get; set; }

/// <summary>
/// Returns whether ThrowOnUndeclaredPropertyForNonOpenType validation setting is enabled.
/// </summary>
Expand Down Expand Up @@ -398,6 +406,7 @@ private void CopyFrom(ODataMessageWriterSettings other)
this.shouldIncludeAnnotation = other.shouldIncludeAnnotation;
this.useFormat = other.useFormat;
this.Version = other.Version;
this.IgnoreNullValues = other.IgnoreNullValues;

this.validations = other.validations;
this.ThrowIfTypeConflictsWithMetadata = other.ThrowIfTypeConflictsWithMetadata;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5139,6 +5139,7 @@ public sealed class Microsoft.OData.ODataMessageWriterSettings {
System.Uri BaseUri { public get; public set; }
bool EnableCharactersCheck { public get; public set; }
bool EnableMessageStreamDisposal { public get; public set; }
bool IgnoreNullValues { public get; public set; }
string JsonPCallback { public get; public set; }
Microsoft.OData.ODataMessageQuotas MessageQuotas { public get; public set; }
Microsoft.OData.ODataUri ODataUri { public get; public set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Combination: 1; TestConfiguration = Format: JsonLight, Request: True, Synchronous: True
Model Present: true
{"@odata.context":"http://odata.org/test/$metadata#CustomerSet/$entity","ID":42,"Hobby":"Hiking"}

Combination: 2; TestConfiguration = Format: JsonLight, Request: False, Synchronous: True
Model Present: true
{"@odata.context":"http://odata.org/test/$metadata#CustomerSet/$entity","ID":42,"Hobby":"Hiking"}

Combination: 3; TestConfiguration = Format: JsonLight, Request: True, Synchronous: False
Model Present: true
{"@odata.context":"http://odata.org/test/$metadata#CustomerSet/$entity","ID":42,"Hobby":"Hiking"}

Combination: 4; TestConfiguration = Format: JsonLight, Request: False, Synchronous: False
Model Present: true
{"@odata.context":"http://odata.org/test/$metadata#CustomerSet/$entity","ID":42,"Hobby":"Hiking"}

Combination: 5; TestConfiguration = Format: JsonLight, Request: True, Synchronous: True
Model Present: true
{"@odata.context":"http://odata.org/test/$metadata#CustomerSet/$entity","ID":44}

Combination: 6; TestConfiguration = Format: JsonLight, Request: False, Synchronous: True
Model Present: true
{"@odata.context":"http://odata.org/test/$metadata#CustomerSet/$entity","ID":44}

Combination: 7; TestConfiguration = Format: JsonLight, Request: True, Synchronous: False
Model Present: true
{"@odata.context":"http://odata.org/test/$metadata#CustomerSet/$entity","ID":44}

Combination: 8; TestConfiguration = Format: JsonLight, Request: False, Synchronous: False
Model Present: true
{"@odata.context":"http://odata.org/test/$metadata#CustomerSet/$entity","ID":44}

Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void PayloadOrderTest()
var nonMLEBaseType = new EdmEntityType("TestModel", "NonMLEBaseType");
nonMLEBaseType.AddKeys(nonMLEBaseType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
model.AddElement(nonMLEBaseType);
var nonMLESet = container.AddEntitySet("NonMLESet", nonMLEBaseType);
var nonMLESet = container.AddEntitySet("NonMLESet", nonMLEBaseType);

var nonMLEType = new EdmEntityType("TestModel", "NonMLEType", nonMLEBaseType);
nonMLEType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true));
Expand All @@ -66,13 +66,13 @@ public void PayloadOrderTest()
var mleType = new EdmEntityType("TestModel", "MLEType", mleBaseType, false, false, true);
mleType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true));
mleType.AddStructuralProperty("Description", EdmCoreModel.Instance.GetString(true));
mleType.AddStructuralProperty("StreamProperty", EdmPrimitiveTypeKind.Stream, isNullable:false);
mleType.AddStructuralProperty("StreamProperty", EdmPrimitiveTypeKind.Stream, isNullable: false);
var mleNav = mleType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "NavProp", Target = otherType, TargetMultiplicity = EdmMultiplicity.Many });
mleSet.AddNavigationTarget(mleNav, otherset);
model.AddElement(mleType);

IEnumerable<EntryPayloadTestCase> testCases = new[]
{
{
new EntryPayloadTestCase
{
DebugDescription = "TypeName at the beginning, nothing else",
Expand All @@ -96,7 +96,7 @@ public void PayloadOrderTest()
new ODataProperty { Name = "Name", Value = "test" },
}
}
.WithAnnotation(new WriteEntryCallbacksAnnotation
.WithAnnotation(new WriteEntryCallbacksAnnotation
{
BeforeWriteStartCallback = (entry) => { entry.TypeName = "TestModel.MLEType"; },
BeforeWriteEndCallback = (entry) => { entry.TypeName = "NonExistingType"; }
Expand Down Expand Up @@ -197,16 +197,16 @@ public void PayloadOrderTest()
new ODataProperty { Name = "ID", Value = (int)42 },
new ODataProperty { Name = "Name", Value = "test" },
}
}.WithAnnotation(new WriteEntryCallbacksAnnotation
}.WithAnnotation(new WriteEntryCallbacksAnnotation
{
BeforeWriteStartCallback = (entry) =>
{
{
entry.EditLink = null;
entry.MediaResource.EditLink = null;
entry.MediaResource.ETag = null;
entry.MediaResource.ContentType = null;
},
BeforeWriteEndCallback = (entry) =>
BeforeWriteEndCallback = (entry) =>
{
entry.EditLink = new Uri("http://odata.org/editlink");
entry.MediaResource.EditLink = new Uri("http://odata.org/mediaeditlink");
Expand Down Expand Up @@ -240,7 +240,7 @@ public void PayloadOrderTest()
testCase.Items,
tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
{
Json = string.Format(CultureInfo.InvariantCulture, testCase.Json,
Json = string.Format(CultureInfo.InvariantCulture, testCase.Json,
string.Empty,
JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ","),
FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
Expand Down Expand Up @@ -338,7 +338,7 @@ public void ActionAndFunctionPayloadOrderTest()
model.AddElement(nonMLEType);
container.AddEntitySet("NonMLEType", nonMLEType);

ODataAction action = new ODataAction
ODataAction action = new ODataAction
{
Metadata = new Uri("http://odata.org/test/$metadata#defaultAction"),
Title = "Default Action",
Expand Down Expand Up @@ -432,14 +432,104 @@ public void ActionAndFunctionPayloadOrderTest()
});
}

[TestMethod, Variation(Description = "Test skipping null values when writing JSON Lite entries with IgnoreNullValues = true.")]
public void IgnoreNullPropertiesInEntryTest()
{
EdmModel model = new EdmModel();
var container = new EdmEntityContainer("TestModel", "TestContainer");
model.AddElement(container);

var customerType = new EdmEntityType("TestModel", "CustomerType", null, false, isOpen: false);
customerType.AddKeys(customerType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
customerType.AddKeys(customerType.AddStructuralProperty("Hobby", EdmCoreModel.Instance.GetString(true)));
model.AddElement(customerType);
var customerSet = container.AddEntitySet("CustomerSet", customerType);

var addressType = new EdmComplexType("TestModel", "AddressType");
addressType.AddStructuralProperty("Street", EdmCoreModel.Instance.GetStream(true));
model.AddElement(addressType);

IEnumerable<EntryPayloadTestCase> testCases = new[]
{
new EntryPayloadTestCase
{
DebugDescription = "Customer instance with all properties set.",
Items = new[] { new ODataResource()
{
TypeName = "TestModel.CustomerType",
Properties = new ODataProperty[]
{
new ODataProperty { Name = "ID", Value = (int)42 },
new ODataProperty { Name = "Hobby", Value = "Hiking" },
}
} },
Model = model,
EntitySet = customerSet,
Json = string.Join("$(NL)",
"{{",
"{0}\"ID\":\"42\", \"Hobby\":\"Hiking\"",
"}}")
},
new EntryPayloadTestCase
{
DebugDescription = "Customer instance without Hobby.",
Items = new[] {new ODataResource()
{
TypeName = "TestModel.CustomerType",
Properties = new ODataProperty[]
{
new ODataProperty { Name = "ID", Value = (int)44 },
new ODataProperty { Name = "Hobby", Value = null },
}
} },
Model = model,
EntitySet = customerSet,
Json = string.Join("$(NL)",
"{{",
"{0}\"ID\":\"44\"",
"}}")
},

};

IEnumerable<PayloadWriterTestDescriptor<ODataItem>> testDescriptors = testCases.Select(testCase =>
new PayloadWriterTestDescriptor<ODataItem>(
this.Settings,
testCase.Items,
tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
{
Json = string.Format(
CultureInfo.InvariantCulture,
testCase.Json,
JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ","),
FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
})
{
DebugDescription = testCase.DebugDescription,
Model = testCase.Model,
PayloadEdmElementContainer = testCase.EntitySet,
PayloadEdmElementType = testCase.EntityType,
SkipTestConfiguration = testCase.SkipTestConfiguration
});

this.CombinatorialEngineProvider.RunCombinations(
testDescriptors,
this.WriterTestConfigurationProvider.JsonLightFormatConfigurationsWithIndent,
(testDescriptor, testConfiguration) =>
{
testConfiguration.MessageWriterSettings.IgnoreNullValues = true;
TestWriterUtils.WriteAndVerifyODataEdmPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
});
}

[TestMethod, Variation(Description = "Test correct serialization format when writing JSON Lite entries with open properties.")]
public void OpenPropertiesInEntryTest()
{
EdmModel model = new EdmModel();
var container = new EdmEntityContainer("TestModel", "TestContainer");
model.AddElement(container);

var openCustomerType = new EdmEntityType("TestModel", "OpenCustomerType", null, false, isOpen:true);
var openCustomerType = new EdmEntityType("TestModel", "OpenCustomerType", null, false, isOpen: true);
openCustomerType.AddKeys(openCustomerType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
model.AddElement(openCustomerType);
var customerSet = container.AddEntitySet("CustomerSet", openCustomerType);
Expand Down Expand Up @@ -494,7 +584,7 @@ public void OpenPropertiesInEntryTest()
"\"type\":\"name\",\"properties\":{{",
"\"name\":\"EPSG:4326\"",
"}}",
"}}",
"}}",
"}}",
"}}")
},
Expand Down Expand Up @@ -526,7 +616,7 @@ public void OpenPropertiesInEntryTest()
tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
{
Json = string.Format(
CultureInfo.InvariantCulture,
CultureInfo.InvariantCulture,
testCase.Json,
JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ","),
FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
Expand Down Expand Up @@ -561,7 +651,7 @@ public void SpatialPropertiesInEntryTest()
customerType.AddStructuralProperty("Location2", EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.GeographyPoint, false));
model.AddElement(customerType);
var customerSet = container.AddEntitySet("CustomerSet", customerType);

ISpatial pointValue = GeographyFactory.Point(32.0, -100.0).Build();

IEnumerable<EntryPayloadTestCase> testCases = new[]
Expand Down Expand Up @@ -590,7 +680,7 @@ public void SpatialPropertiesInEntryTest()
"\"type\":\"name\",\"properties\":{{",
"\"name\":\"EPSG:4326\"",
"}}",
"}}",
"}}",
"}}",
"}}")
},
Expand All @@ -617,7 +707,7 @@ public void SpatialPropertiesInEntryTest()
"\"type\":\"name\",\"properties\":{{",
"\"name\":\"EPSG:4326\"",
"}}",
"}}",
"}}",
"}}",
"}}")
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@
<Content Include="JsonLight\JsonLightEntryWriterTests.OpenPropertiesInEntryTest.approved.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="JsonLight\JsonLightEntryWriterTests.IgnoreNullPropertiesInEntryTest.approved.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="JsonLight\JsonLightPropertyWriterTests.WriteFloatingPointValue.approved.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand Down

0 comments on commit 2de403d

Please sign in to comment.