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

Json serialization of longs to strings #70

Closed
CheloXL opened this issue Jun 11, 2022 · 4 comments · Fixed by #117
Closed

Json serialization of longs to strings #70

CheloXL opened this issue Jun 11, 2022 · 4 comments · Fixed by #117

Comments

@CheloXL
Copy link

CheloXL commented Jun 11, 2022

I know this is a very specific case, but... Javascript doesn't support longs. They are trimmed down to the nearest 53bit integer. I have a DB where Ids are longs so I implemented a custom json converter for my webapi that simply writes longs as strings and parse them back from strings (instead of using real js numbers).

I can't do the same with STI, as the serializer it generates simply does a writer.WriteNumberValue(value.Value);. That's fine inside the .net realm, but not in javascript.

I would like an option to be able to specify that longs should be [de]serialized as strings instead of numbers.

Would that be possible? Not sure about any other options that could solve the problem in a generic way.

@jdrames
Copy link

jdrames commented Oct 13, 2022

Wouldn't that concern be part of your application? I would assume something like AutoMapper to map from your domain db object to the DTO model where Id would be long StronglyTypedId backed value in your domain db entity and ID would then be a string in your DTO object.

[assembly: StronglyTypedIdDefaults(
    backingType: StronglyTypedIdBackingType.Long,
    converters: StronglyTypedIdConverter.SystemTextJson)]

...
[StronglyTypedId]
public partial struct ItemId { }

public class DbEntity
{
    public ItemId Id { get; set; }
    public string Name { get; set; }
}

public class DbEntityDTO
{
    public string Id { get; set; }
    public string Name { get; set; }
}
...
Mapper.CreateMap<DbEntity, DbEntityDTO>()
    .ForMember(dest=>dest.Id, opt=>opt.MapFrom(src=>Convert.ToString(src.Id)));
    
...
var source = new DbEntity{
   Id = new ItemId(420L),
   Name = "John Smith"
};

DbEntityDTO result = Mapper.Map<DbEntity, DbEntityDTO>(source);

@CheloXL
Copy link
Author

CheloXL commented Oct 13, 2022

If you have an anemic domain, you could. Or if your domain is 99% similar to your DTO. In my case, domain objects are not DB entities, and while I can have some properties in common between entity<->dto, I never map them using a mapper. At least not for commands. Queries, on the other hand, do get mapped, since those are usually quite similar to what I have in the DB.

@jdrames
Copy link

jdrames commented Oct 13, 2022

I guess I'm just lost on where the use case is for this.
When displaying data out in an API I would use a dto object and simply convert the long to a string for the specified property. Same for incoming data via javascript. I would use an input dto, apply some fluent validation on that and also the json number handling attributes. I'd never map an incoming value directly to the domain object and use it to then do a command.

@andrewlock
Copy link
Owner

Sorry for the delay with this 😳. To be honest I got overwhelmed with how to handle the big range of feature requests and options. I think I've found an answer in the big redesign of the library in this PR:

The main idea is to make the library much more maintainable while also giving people a mechanism to customise the generated IDs as much as they like. This will make it easy to make changes like this, as you can simply provide a custom template that you can use which has the desired functionality 🙂

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

Successfully merging a pull request may close this issue.

3 participants