TL; dr:
I register the serializer and deserializer in the structure. The serializer is not called, but there is a deserializer.
How can i fix this? It works correctly on reference types, and doing JsConfig<Position>.TreatValueAsRefType = true; also did not help.
Long version:
I save two complex types using ORMLite: Position (structure, from the external DotSpatial library that we do not control) and Tuple.
To be able to properly store / read them from the database, I defined their serializers and deserializers:
// Struct. Called by position.ToJsv(), NOT called by ORMLite connection.Insert() . JsConfig<Position>.SerializeFn = position => { string str = position.ToString(null, CultureInfo.InvariantCulture); return str; // Breakpoint here. }; // Struct. Called in both. JsConfig<Position>.DeSerializeFn = position => Position.Parse(position, CultureInfo.InvariantCulture); // Reference type. Works fine. JsConfig<Tuple<double, double>>.SerializeFn = tuple => string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", tuple.Item1, CultureInfo.InvariantCulture.TextInfo.ListSeparator, tuple.Item2 ); // Works fine too. JsConfig<Tuple<double, double>>.DeSerializeFn = tuple => { var values = tuple.Split(new[] { CultureInfo.InvariantCulture.TextInfo.ListSeparator }, StringSplitOptions.None); double item1, item2; if (values.Length == 2 && double.TryParse(values[0], out item1) && double.TryParse(values[1], out item2)) { var result = new Tuple<double, double>(item1, item2); return result; } throw new ArgumentException("Could not parse easting and northing from database; malformatted?", "tuple"); };
Debugging
The breakpoint in the deserializer gets when reading from the database using ORMLite: connection.Where<T>(item => item.Foo == bar) .
Γ The breakpoint in the serializer does not fall when writing to the database using ORMLite: connection.Insert(item) .
I thought that maybe the serializer was not registered properly, so I called .ToJsv() on the object.
var lat = Latitude.Parse("00Β°00'02.7451\"N", CultureInfo.InvariantCulture); var lon = Longitude.Parse("013Β°29'17.3270\"W", CultureInfo.InvariantCulture); Position pos = new Position(lat, lon); string foo = pos.ToJsv();
When the breakpoint is reached, str = 00Β°00'02.7451"N,013Β°29'17.3270"W
But when inserting with ORMLite, the breakpoint does not hit, and I get values ββin the database, such as 00Β°00'02,7451"N;013Β°29'17,3270"W - pay attention to commas due to culture.
The database stores culture-dependent values ββ!: (
Attempts
Since this only happens in structures, I tried to register a type that would be considered as a reference type, but that didn't seem to work.
JsConfig<Position>.TreatValueAsRefType = true;
Update:
I am using the ORMLite.PostgreSQL Nuget package (v 3.9.70). It includes ServiceStack.Text (v 3.9.70) and Npgsql (v 2.0.11).
I want to try to get the code from the source control and debug it directly, but so far I don't have time.
Position structure is defined in an external library, which I cannot change.
Minimalist pattern
I downloaded a minimalist sample at https://gist.github.com/aneves/7830776 , which shows the following output:
Thing, current culture: 12,6;10,9 Thing, invariant culture: 12.6,10.9 Thing, from Jsv: "12,6;10,9" >> deserializing 10;35 >> Could not parse value, it is malformed. (10;35) Found this: Box[A: 0;0] Press any key to continue . . .