cosullivan / Hypermedia

Hypermedia library for .NET
http://cainosullivan.com/Hypermedia
MIT License
47 stars 12 forks source link

Custom Recasting During Deserialization #37

Open hughesjs opened 2 years ago

hughesjs commented 2 years ago

The API I'm working with has Latitude and Longitude fields encoded as strings. Ideally, I want these on my models as doubles.

So far, the best I've been able to come up with is to do:

//...
.Field(nameof(LaunchSite.Latitude)).Deserialization().Rename(nameof(LaunchSite.LatitudeAsString))
.Field(nameof(LaunchSite.Longitude)).Deserialization().Rename(nameof(LaunchSite.LongitudeAsString));

and then have this on my class:

internal string LongitudeAsString
{
     init => Longitude = double.Parse(value);
}

internal string LatitudeAsString
{
     init => Latitude = double.Parse(value);
}

This did require a slight change to the RuntimeFieldAccessor to use Type.GetRuntimeProperties().Single(...) rather than Type.GetRuntimeProperty(name) to let it see the internal properties but this still doesn't quite seem to work. I end up with doubled-up field names in JsonApiSerializer.DeserializeFields().

So I've had to result to adding internal string properties called Latitude and Longitude and then having public, expression bodied properties called LatitudeDegs and LongitudeDegs that both parse their relevant string fields but this feels like a bodge on a bodge at this point and I'd prefer a cleaner solution.

I think adding something that would allow us to go .Deserialize().Custom<TIn, TOut>(func<TIn, TOut> deserializeFunc) would be nice.

Any thoughts on this or ideas for a workaround to my issue?