NodaMoney icon indicating copy to clipboard operation
NodaMoney copied to clipboard

Currency malformed on deserialization

Open josefblaha opened this issue 2 years ago • 2 comments

Take a Currency object and do a serialization roundtrip. The resulting object contains only Code property value, the others are on default values:

var original = Currency.FromCode("CZK");
// Code CZK
// DecimalDigits 2
// EnglishName Czech koruna
// IsObsolete False
// MajorUnit 1
// MinorUnit 0.01
// Namespace ISO-4217
// Number 203
// Symbol Kč
// ValidFrom null
// ValidTo null

var str = JsonConvert.SerializeObject(original);
// "{"Code":"CZK"}"

var result = JsonConvert.DeserializeObject<Currency>(str);
// Code CZK
// DecimalDigits 0
// EnglishName null
// IsObsolete False
// MajorUnit 1
// MinorUnit 1
// Namespace null
// Number null
// Symbol null
// ValidFrom null
// ValidTo null

Using the deserialized result currency to construct a Money does not work well:

var m = new Money(123.45m, result);
// m.Amount stripped to 123

m.ToString();
// throws ArgumentNullException

It looks like a bug. Or am I missing anything? A Money object survives serialization roundtrip without any problems.

Environment: .NET 6 NodaMoney 1.0.5 Newtownsoft.Json 13.0.1

josefblaha avatar Jun 29 '22 09:06 josefblaha

I can't reproduce this behavior. I'm using the test below.

  var currency = Currency.FromCode("CZK");
            
  string json = JsonConvert.SerializeObject(currency);
  var clone = JsonConvert.DeserializeObject<Currency>(json);

  clone.Should().Be(currency);
  clone.Namespace.Should().NotBeNull();
  clone.Number.Should().NotBe(default);

You are saying the following properties after deserializing are null which is not possible, because they are structs.

// Number null
// Symbol null
// ValidFrom null
// ValidTo null

RemyDuijkeren avatar Jul 18 '22 05:07 RemyDuijkeren

On my machine, that test fails on second assertion because of Namespace being null.

I think we're on different version. I use NuGet package NodaMoney 1.0.5 released on 29/8/2018 corresponding to commit 5ee1065. In that version, the Currency struct is marked with DataContractAttribute and it looks like Newtonsoft.Json is using that to (de)serialize Code property only. Maybe you test with master branch; it includes commit 3c0d3e0, in which some serialization changes were made.

Why couldn't those properties be null? Number and Symbol are strings, ValidFrom and ValidTo are nullable dates.

josefblaha avatar Jul 25 '22 06:07 josefblaha