Today we were experiencing some weird behavior when running an integration test with DillPickle, where – apparently – values of doubles would lose their decimal point when they were transferred in messages from our test to an NServiceBus service.
Stopping the service and inspecting the message in the queue quickly revealed a message that looked somewhat like this:
1 2 3 4 5 |
<Messages> <SetCurrentValueMessage> <Value>13.56</Value> </SetCurrentValueMessage> </Messages> |
which is all fine and dandy.
Now, I’m used to being Danish, so I know that we’re somewhat deviant in regards to our decimal point – “,” – so we quickly diagnosed the problem: Our integration tests were running with the invariant culture, to allow us to parse Gherkin files in English and use “.” as the decimal point – but Windows and everything else was running with da-DK, so 13.56 would be improperly deserialized to the value 1356 when it reached our NServiceBus service.
Solution: Normalize the culture of all the processes of our system.
Our first attempt was to modify the culture in our endpoint configuration like so:
1 2 3 4 5 6 7 8 9 |
public class EndpointConfiguration : IConfigureThisEndpoint, AsA_Server { public EndpointConfiguration() { // does NOT work! Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; } } |
but obviously this did not work, because NServiceBus does not deserialize messages on this thread!
Our solution was to create a message module, which seems to get called before transport messages are deserialized, setting the culture in there – like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class SetCurrentCultureMessageModule : IMessageModule { public void HandleBeginMessage() { // works! Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; } public void HandleEndMessage() { } public void HandleError() { } } |
In the future I’ll make sure that the culture is explicitly set in all processes of systems I am building. It’s kind of scary that errors could happen where stuff like “debit account 100.00” could be mis-interpreted as “debit account 10000”!! 😮
Hey,
It is even more scary that we apparently didn’t have a unit-test to cover/verify the simple requirement
“Transfer doubles from A to B”
:o)
Yeah – I guess that justifies going through all kinds of mad trouble in order to make the integration tests run… 😉
We’re fixing our serialization (v2.5.1 and on) so that this won’t happen anymore.