Skip to content

Custom ODataSerializerProvider never instanciated and its GetEdmTypeSerializer method not called #1444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
magneticcore opened this issue Mar 18, 2025 · 1 comment
Assignees
Labels
wontfix This will not be worked on

Comments

@magneticcore
Copy link

magneticcore commented Mar 18, 2025

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>, in OData, but the ODataCustomODataSerializerProvider is never instanciated.

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 magneticcore added the bug Something isn't working label Mar 18, 2025
@xuzhg xuzhg self-assigned this Mar 18, 2025
xuzhg added a commit to xuzhg/WebApiSample that referenced this issue Mar 18, 2025
@xuzhg
Copy link
Member

xuzhg commented Mar 18, 2025

@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.

@xuzhg xuzhg added wontfix This will not be worked on and removed bug Something isn't working labels Mar 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants