WebApi
WebApi copied to clipboard
ODataActionPayloadDeserializer failed to deserialize action parameter when it's a 2d array
We defined an OData action with a 2d array parameter:
public IEnumerable<IEnumerable<object>> TestList { get; set; }
The OData entity model is registered as
<Action Name="TestAction">
<Parameter Name="testList" Type="Collection(System.Collections.Generic.IEnumerable_1OfInt32)" />
</Action>
ODataActionPayloadDeserializer throws exception for this 2d array action parameter:
System.InvalidCastException: 'Unable to cast object of type 'Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataResourceSetWrapper' to type 'Microsoft.AspNetCore.OData.Formatter.Wrapper.ODataNestedResourceInfoWrapper'.'
Assemblies affected
OData WebApi lib 7.2.2, I also tested latest main branch, it has the same issue.
Reproduce steps
It can be reproduced in unit test of ODataActionPayloadDeserializer
- Go to AspNetCoreOData\test\Microsoft.AspNetCore.OData.Tests\Formatter\Deserialization\ODataActionPayloadDeserializerTest.cs`
- Change schema of
MyAddress
as
public class MyAddress
{
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public int ZipCode { get; set; }
public IEnumerable<IEnumerable<int>> TestList { get; set; }
}
- Construct test body in
Can_DeserializePayload_WithComplexParameters
as
const string Body = @"{ ""Quantity"": 1 , ""Address"": { ""StreetAddress"":""1 Microsoft Way"", ""City"": ""Redmond"", ""State"": ""WA"", ""ZipCode"": 98052, ""TestList"": [[1, 2, 3], [3, 4, 5]]} }";
- Run the test and see exception, if
TestList
is ofIEnumerable<int>
type, and ifTestList
inBody
is of 1d array, everything works well.
Expected result
ODataActionPayloadDeserializer
can correctly deserialize 2d array without throwing exceptions, if it's a Edm model registration error, please make the error message more clear.
Tiny tips: Collection of the collection is not following up OData protocol. You can define a complex type to contain 'IEnumerable
@xuzhg Thanks for letting me know, but I also find an issue here: https://github.com/OData/odata.net/issues/505 saying 2d array is supported, so maybe we just need to find a way to define a collection of Edm.Untyped
type?
@cloudsere Partial support for collection of collections is the form of collection of untyped or just untyped. We do not support a collection of primitive collections, i.e. (IEnumerable<IEnumerable<int>>
). You'd need to define the property as IEnumerable<object>
. However, this is currently not supported in 7x and the support may also be limited in 8x
Because untyped provides limited support both in materialization and query options it's recommended to use a collection of complex types as suggested by @xuzhg above.