WebApi icon indicating copy to clipboard operation
WebApi copied to clipboard

Case-Insensitive Property Matching NullRefs

Open ificator opened this issue 3 years ago • 1 comments

After upgrading to 7.5.14 we observed a NullReferenceException in one of our test cases. After drilling in we found it was related to https://github.com/OData/WebApi/pull/2311 which swapped to allowing case-insensitive property matching during deserialization. We've worked around this by opting into the old behavior, but the nullref needs to be fixed.

Assemblies affected

Microsoft.AspNet.OData 7.5.14

Reproduce steps

  1. Send a POST request to update the value of myProperty on an open-type using myproperty as the name and have a null value
{
  "myproperty": null
}

Expected result

Request should succeed

Actual result

Request fails

Additional detail

It looks like the property is found (i.e. it determines it's NOT dynamic), but it tries to treat a null value as a primitive which causes ConvertPrimitiveValue to fail:

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Object.GetType()
   at Microsoft.AspNet.OData.Formatter.EdmPrimitiveHelpers.ConvertPrimitiveValue(Object value, Type type)
   at Microsoft.AspNet.OData.Formatter.Deserialization.DeserializationHelpers.SetDeclaredProperty(Object resource, EdmTypeKind propertyKind, String propertyName, Object propertyValue, IEdmProperty edmProperty, ODataDeserializerContext readContext)
   at Microsoft.AspNet.OData.Formatter.Deserialization.DeserializationHelpers.ApplyProperty(ODataProperty property, IEdmStructuredTypeReference resourceType, Object resource, ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)
   at Microsoft.AspNet.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyStructuralProperties(Object resource, ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
   at Microsoft.AspNet.OData.Formatter.Deserialization.ODataResourceDeserializer.ApplyResourceProperties(Object resource, ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
   at Microsoft.AspNet.OData.Formatter.Deserialization.ODataResourceDeserializer.ReadResource(ODataResourceWrapper resourceWrapper, IEdmStructuredTypeReference structuredType, ODataDeserializerContext readContext)
   at Microsoft.AspNet.OData.Formatter.Deserialization.ODataResourceSetDeserializer.<ReadResourceSet>d__5.MoveNext()

ificator avatar Mar 14 '22 17:03 ificator

It looks like there's a difference in the property.Value that's triggering the failure. In the case where you pass in myProperty oDataValue is null, while when you pass in myproperty oDataValue is not null: image

This makes the kind be Primitive instead of None and it triggers ConvertPrimitiveValue.

ificator avatar Mar 14 '22 18:03 ificator

@ificator Was the issue resolved by later versions of the library?

KenitoInc avatar Sep 05 '23 13:09 KenitoInc