Skip to content
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

Custom type mapping #2464

Closed
manoack opened this issue Jul 21, 2022 · 4 comments
Closed

Custom type mapping #2464

manoack opened this issue Jul 21, 2022 · 4 comments
Assignees

Comments

@manoack
Copy link

manoack commented Jul 21, 2022

I try to implement a custom mapping. For some fields I try to map Edm.Decimal to System.String using a custom conversion attribute. I don't find an approach. Is it possible?

Additional detail

In my server code I want to deal with string fields (native database content). From WebApi I try to deal with decimal values. But approaches with JsonConvert attributes fail (no effect).

@xuzhg
Copy link
Member

xuzhg commented Jul 25, 2022

@manoack
Copy link
Author

manoack commented Jul 27, 2022

@manoack Is https://github.com/OData/odata.net/blob/master/src/Microsoft.OData.Core/ODataPayloadValueConverter.cs what you are looking for?

I'm not sure, I find no way to inject it. I try to extend the ODataRoutingExample:

.AddRouteComponents("", model0, action => { action.AddSingleton(typeof(ODataPayloadValueConverter), new MyConverter()); })
But code in my converter is not called. I see similar problem here:
OData/AspNetCoreOData#732

I suppose, AddRouteComponents add a default implementation of ODataPayloadValueConverter with more priority and I can't change this behaviour.

Is there any example to implement such custom converter correctly?

@desirade-fm
Copy link

I have the same problem.

@gathogojr
Copy link
Contributor

@manoack It's not clear to me whether what you want to do is to format decimals stored in the database as strings or to format decimals to strings. Either way the custom ODataPayloadValueConverter should work.
Please note that this converter is used during serialization, not deserialization.
Here's how you'd go about implementing the custom converter:

public class MyConverter : ODataPayloadValueConverter
{
    public override object ConvertToPayloadValue(object value, IEdmTypeReference edmTypeReference)
    {
        if (edmTypeReference.PrimitiveKind() == EdmPrimitiveTypeKind.Decimal)
        {
            var decimalValue = (decimal)value;
            return decimal.ToString("#.##");
        }

        return base.ConvertToPayloadValue(value, edmTypeReference);
    }
}

The custom converter can be injected in the dependency injection container as follows:

services.AddControllers().AddOData(
    options => options.AddRouteComponents(
        routePrefix: string.Empty,
        model: model0,
        configureServices: sp => sp.AddSingleton(
            serviceType: typeof(ODataPayloadValueConverter),
            implementationInstance: new MyConverter())));

There's nothing like this:

AddRouteComponents add a default implementation of ODataPayloadValueConverter with more priority and I can't change this behaviour

This is the way to do it using a custom converter. You can refer to a similar issue here with a similar proposal/solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants