Skip to content

Commit

Permalink
Enable updating top-level properties to null.
Browse files Browse the repository at this point in the history
Support for writing top-level properties with null values at
the time @odata.null:true was removed. The 4.0 spec states in
1.2.3 Requesting Individual Properties that if the property is
single-valued and has the null value, the service responds with
204 No Content. The library is correct in throwing an exception
when asked to write a null top-level values.

This change adds support for the scenario in the following ways:

1.) Writing a null top-level value still throws but with a well-defined
    error message.

2.) The scenario can be enabled by setting library to 6 compatibility mode in the reader and
    writer settings, i.e. settings.LibraryCompatibility = ODataLibraryCompatibility.Version6.
    In this case, the value is read and written as: "@odata.null":true

3.) The reader will support reading "@odata.null":true. However, it does not use
    the library compatibility mode to do so. The library compatibility mode
    has been added to the reader for the completness of the API.
  • Loading branch information
robward-ms committed Mar 5, 2018
1 parent f023620 commit 9d625ff
Show file tree
Hide file tree
Showing 31 changed files with 435 additions and 147 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AllowCrossTargeting>true</AllowCrossTargeting>
Expand Down Expand Up @@ -308,26 +308,26 @@
<Link>Microsoft\OData\Core\JsonLight\ODataJsonLightWriterUtils.cs</Link>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\JsonLight\ReorderingJsonReader.cs">
<Link>Microsoft\OData\Core\JsonLight\ReorderingJsonReader.cs</Link>
</Compile>
<Link>Microsoft\OData\Core\JsonLight\ReorderingJsonReader.cs</Link>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\JsonLight\ODataJsonLightBatchBodyContentReaderStream.cs">
<Link>Microsoft\OData\Core\JsonLight\ODataJsonLightBatchBodyContentReaderStream.cs</Link>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\JsonLight\ODataJsonLightBatchReader.cs">
<Link>Microsoft\OData\Core\JsonLight\ODataJsonLightBatchReader.cs</Link>
</Compile>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\JsonLight\ODataJsonLightBatchWriter.cs">
<Link>Microsoft\OData\Core\JsonLight\ODataJsonLightBatchWriter.cs</Link>
</Compile>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\JsonLight\ODataJsonLightBatchPayloadItemPropertiesCache.cs">
<Link>Microsoft\OData\Core\JsonLight\ODataJsonLightBatchPayloadItemPropertiesCache.cs</Link>
</Compile>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\JsonLight\ODataJsonLightBatchReaderStream.cs">
<Link>Microsoft\OData\Core\JsonLight\ODataJsonLightBatchReaderStream.cs</Link>
</Compile>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\JsonLight\ODataJsonLightBatchAtomicGroupCache.cs">
<Link>Microsoft\OData\Core\JsonLight\ODataJsonLightBatchAtomicGroupCache.cs</Link>
</Compile>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\Json\BufferingJsonReader.cs">
<Link>Microsoft\OData\Core\Json\BufferingJsonReader.cs</Link>
</Compile>
Expand Down Expand Up @@ -453,13 +453,13 @@
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\MultipartMixed\ODataMultipartMixedBatchInputContext.cs">
<Link>Microsoft\OData\Core\MultipartMixed\ODataMultipartMixedBatchInputContext.cs</Link>
</Compile>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\MultipartMixed\ODataMultipartMixedBatchOutputContext.cs">
<Link>Microsoft\OData\Core\MultipartMixed\ODataMultipartMixedBatchOutputContext.cs</Link>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\MultipartMixed\ODataMultipartMixedBatchReader.cs">
<Link>Microsoft\OData\Core\MultipartMixed\ODataMultipartMixedBatchReader.cs</Link>
</Compile>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\MultipartMixed\ODataMultipartMixedBatchReaderStream.cs">
<Link>Microsoft\OData\Core\MultipartMixed\ODataMultipartMixedBatchReaderStream.cs</Link>
</Compile>
Expand All @@ -471,7 +471,7 @@
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\MultipartMixed\DependsOnIdsTracker.cs">
<Link>Microsoft\OData\Core\MultipartMixed\DependsOnIdsTracker.cs</Link>
</Compile>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\NonDisposingStream.cs">
<Link>Microsoft\OData\Core\NonDisposingStream.cs</Link>
</Compile>
Expand Down Expand Up @@ -1356,7 +1356,7 @@
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\UriParser\SyntacticAst\QueryTokenKind.cs">
<Link>Microsoft\OData\Core\UriParser\SyntacticAst\QueryTokenKind.cs</Link>
</Compile>
</Compile>
<Compile Include="$(ODataCrossTargettingSourcePath)\UriParser\SyntacticAst\RangeVariableToken.cs">
<Link>Microsoft\OData\Core\UriParser\SyntacticAst\RangeVariableToken.cs</Link>
</Compile>
Expand Down Expand Up @@ -1554,6 +1554,9 @@
<Compile Include="..\ODataEdmPropertyAnnotation.cs">
<Link>Microsoft\OData\Core\ODataEdmPropertyAnnotation.cs</Link>
</Compile>
<Compile Include="..\ODataLibraryCompatibility.cs">
<Link>Microsoft\OData\Core\ODataLibraryCompatibility.cs</Link>
</Compile>
<Compile Include="..\ODataNestedResourceInfoSerializationInfo.cs">
<Link>Microsoft\OData\Core\ODataNestedResourceInfoSerializationInfo.cs</Link>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<AssemblyName>Microsoft.OData.Core</AssemblyName>
Expand Down Expand Up @@ -292,7 +292,7 @@
</Compile>
<Compile Include="..\JsonLight\ODataJsonLightBatchAtomicGroupCache.cs">
<Link>JsonLight\ODataJsonLightBatchAtomicGroupCache.cs</Link>
</Compile>
</Compile>
<Compile Include="..\JsonLight\ODataJsonLightBatchPayloadItemPropertiesCache.cs">
<Link>JsonLight\ODataJsonLightBatchPayloadItemPropertiesCache.cs</Link>
</Compile>
Expand All @@ -301,13 +301,13 @@
</Compile>
<Compile Include="..\JsonLight\ODataJsonLightBatchWriter.cs">
<Link>JsonLight\ODataJsonLightBatchWriter.cs</Link>
</Compile>
</Compile>
<Compile Include="..\JsonLight\ODataJsonLightBatchReaderStream.cs">
<Link>JsonLight\ODataJsonLightBatchReaderStream.cs</Link>
</Compile>
<Compile Include="..\JsonLight\ODataJsonLightBatchBodyContentReaderStream.cs">
<Link>JsonLight\ODataJsonLightBatchBodyContentReaderStream.cs</Link>
</Compile>
</Compile>
<Compile Include="..\JsonLight\ODataJsonLightParameterDeserializer.cs">
<Link>JsonLight\ODataJsonLightParameterDeserializer.cs</Link>
</Compile>
Expand Down Expand Up @@ -499,7 +499,7 @@
</Compile>
<Compile Include="..\MultipartMixed\ODataMultipartMixedBatchReader.cs">
<Link>MultipartMixed\ODataMultipartMixedBatchReader.cs</Link>
</Compile>
</Compile>
<Compile Include="..\MultipartMixed\ODataMultipartMixedBatchReaderStream.cs">
<Link>MultipartMixed\ODataMultipartMixedBatchReaderStream.cs</Link>
</Compile>
Expand All @@ -508,7 +508,7 @@
</Compile>
<Compile Include="..\MultipartMixed\ODataMultipartMixedBatchWriterUtils.cs">
<Link>MultipartMixed\ODataMultipartMixedBatchWriterUtils.cs</Link>
</Compile>
</Compile>
<Compile Include="..\MultipartMixed\DependsOnIdsTracker.cs">
<Link>MultipartMixed\DependsOnIdsTracker.cs</Link>
</Compile>
Expand Down Expand Up @@ -707,6 +707,9 @@
<Compile Include="..\ODataJsonDateTimeFormat.cs">
<Link>ODataJsonDateTimeFormat.cs</Link>
</Compile>
<Compile Include="..\ODataLibraryCompatibility.cs">
<Link>ODataLibraryCompatibility.cs</Link>
</Compile>
<Compile Include="..\ODataMediaType.cs">
<Link>ODataMediaType.cs</Link>
</Compile>
Expand Down Expand Up @@ -982,7 +985,7 @@
</Compile>
<Compile Include="..\TypeUtils.cs">
<Link>TypeUtils.cs</Link>
</Compile>
</Compile>
<Compile Include="..\UnknownEntitySet.cs">
<Link>UnknownEntitySet.cs</Link>
</Compile>
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.OData.Core/IWriterValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,10 @@ void ValidateTypeKind(EdmTypeKind actualTypeKind,
/// <param name="expectedPropertyTypeReference">The expected property type or null if we
/// don't have any.</param>
/// <param name="propertyName">The name of the property.</param>
/// <param name="isTopLevel">true if the property is top-level.</param>
/// <param name="model">The model used to get the OData version.</param>
void ValidateNullPropertyValue(IEdmTypeReference expectedPropertyTypeReference,
string propertyName, IEdmModel model);
string propertyName, bool isTopLevel, IEdmModel model);

/// <summary>
/// Validates a null collection item against the expected type.
Expand Down
7 changes: 7 additions & 0 deletions src/Microsoft.OData.Core/JsonLight/JsonLightConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ internal static class JsonLightConstants
/// <summary>The separator of property annotations.</summary>
internal const char ODataPropertyAnnotationSeparatorChar = '@';

/// <summary>
/// The 'null' property name for the Json Light value property.
/// This is an OData 3.0 protocol element used for compatibility
/// with 6.x library version.
/// </summary>
internal const string ODataNullPropertyName = "null";

/// <summary>The value 'true' for the OData null annotation.</summary>
internal const string ODataNullAnnotationTrueValue = "true";

Expand Down
9 changes: 8 additions & 1 deletion src/Microsoft.OData.Core/JsonLight/ODataAnnotationNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ internal static class ODataAnnotationNames
ODataNavigationLinkUrl,
ODataDeltaLink,
ODataRemoved,
ODataDelta
ODataDelta,
ODataNull,
},
StringComparer.Ordinal);

Expand Down Expand Up @@ -100,6 +101,12 @@ internal static class ODataAnnotationNames
/// <summary>The 'odata.delta' annotation name.</summary>
internal const string ODataDelta = "odata.delta";

/// <summary>
/// The OData Null annotation name. This is an OData 3.0 protocol element
/// used for compatibility with 6.x library version.
/// </summary>
internal const string ODataNull = "odata.null";

/// <summary>
/// Returns true if the <paramref name="annotationName"/> starts with "odata.", false otherwise.
/// </summary>
Expand Down
Loading

0 comments on commit 9d625ff

Please sign in to comment.