AspNetCoreOData
AspNetCoreOData copied to clipboard
Custom ODataSerializerProvider never instanciated and its GetEdmTypeSerializer method not called
Assemblies affected ASP.NET Core OData 8.2.4
Describe the bug
In a webapi project, I would like to customize ODataSerializerProvider by deriving it in ODataCustomODataSerializerProvider class to serialize a custom type, ie Dictionary<int, List
Reproduce steps
public class ODataCustomODataSerializerProvider : ODataSerializerProvider
{
public ODataCustomODataSerializerProvider(IServiceProvider serviceProvider):
base(serviceProvider)
{
}
public override IODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
{
if (edmType.FullName() == typeof(Dictionary<int, List<int>>).FullName)
{
// return Do something
}
return base.GetEdmTypeSerializer(edmType);
}
}
To initialize it in OData, the following instructions are used in Startup:
option.AddRouteComponents(Configuration["Mvc:ApiName"], GetEdmModelV1(), builder =>
{
builder.AddSingleton<ODataSerializerProvider, ODataCustomODataSerializerProvider>();
});
Then in a OData derived controller, I call its method GetTest():
class ODataTestController: ODataController {
[HttpGet("GetTest()")]
public IActionResult GetTest()
{
var a = new Dictionary<int, List<int>>();
a.Add(10, new List<int>() { 20, 20, 20 });
a.Add(20, new List<int>() { 30, 30, 30 });
return Ok(new TestInfoDto() { GroupTypes = a });
}
}
With TestInfoDto, complexe type:
public class TestInfoDto
{
public Dictionary<int, List<int>> GroupTypes { get; set; } = new Dictionary<int, List<int>>();
}
Rregistered in OData by:
builder.AddComplexType(typeof(TestInfoDto));
Expected behavior The method GetEdmTypeSerializer of the ODataCustomODataSerializerProvider must be called when OData needs to serialize data from the method GetTest() of derived ODataController.
What is wrong? Or what is missing?
@magneticcore I created sample based on your codes and made it work as expected. Please check that at: https://github.com/xuzhg/WebApiSample/blob/main/IssuesOnWebApi/issue1444_CustomSerializerProvider/readme.md.
Be noted, OData works fine using the POCO class, however, the Dictionary is not a POCO class, is there any reason that you have to use the Dictionary<int, List<int>> to define the property.
Be noted for OData team, OData core vocabulary introduces the 'Core.Dictionary' as Open complex type. Consider to use this Edm complex type to build the C# dictionary meanwhile use the OpenPropertyConstraint to limit the key/value type of the Dictionary.