Skip to content

Commit

Permalink
Fix subtle bug when deserializing property without value
Browse files Browse the repository at this point in the history
  • Loading branch information
gathogojr committed Sep 6, 2024
1 parent 1368836 commit 5e18dff
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,14 @@ public virtual void ApplyStructuralProperties(object resource, ODataResourceWrap
throw new ArgumentNullException(nameof(resourceWrapper));
}

foreach (ODataProperty property in resourceWrapper.Resource.Properties)
foreach (ODataPropertyInfo propertyInfo in resourceWrapper.Resource.Properties)
{
if (!(propertyInfo is ODataProperty property))
{
// Cannot deserialize property without value
continue;
}

ApplyStructuralProperty(resource, property, structuredType, readContext);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ private static void ReadODataItem(ODataReader reader, Stack<ODataItemWrapper> it
resourceSetParentWrapper.Items.Add(new ODataPrimitiveWrapper((ODataPrimitiveValue)reader.Item));
break;

case ODataReaderState.NestedProperty:
// Property without value - do nothing
break;

default:
Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state.");
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,38 @@ public void ReadAsync_ThrowsOnUnknownEntityType()
typeof(Product), _readContext).Wait(), "The property 'Concurrency' does not exist on type 'ODataDemo.Product'. Make sure to only use property names that are defined by the type or mark the type as open type.");
}

[Fact]
public async Task ReadAsync_ForPropertyWithoutValue()
{
// Arrange
string content = "{" +
"\"ID\":0," +
"\"Name\":\"Bread\"," +
"\"Description\":\"Whole grain bread\"," +
"\"PublishDate\":\"1997-07-01\"," +
"\"[email protected]\":\"#Edm.DateTimeOffset\"," + // OData annotation - Property without value
"\"[email protected]\":true," + // Custom annotation - Property without value
"\"Rating\":4," +
"\"Price\":2.5" +
"}";

ODataResourceDeserializer deserializer = new ODataResourceDeserializer(_deserializerProvider);

// Act
Product product = await deserializer.ReadAsync(
GetODataMessageReader(content, _edmModel),
typeof(Product),
_readContext) as Product;

// Assert
Assert.Equal(0, product.ID);
Assert.Equal(4, product.Rating);
Assert.Equal(2.5m, product.Price);
Assert.Equal(product.PublishDate, new Date(1997, 7, 1));
Assert.Null(product.ReleaseDate);
Assert.Null(product.DiscontinuedDate);
}

private static ODataMessageReader GetODataMessageReader(IODataRequestMessage oDataRequestMessage, IEdmModel edmModel)
{
return new ODataMessageReader(oDataRequestMessage, new ODataMessageReaderSettings(), edmModel);
Expand Down

0 comments on commit 5e18dff

Please sign in to comment.