Announcement

Collapse
No announcement yet.

[CLOSED] [JSON #4] [1.0] JsonConvert.SerialiseObject doesn't pass ctor arguments and so validation may throw

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    [CLOSED] [JSON #4] [1.0] JsonConvert.SerialiseObject doesn't pass ctor arguments and so validation may throw

    If I have a class with constructor argument validation like this -

    public class MyString
    {
        public MyString(string value)
        {
            if (string.IsNullOrWhiteSpace(value))
                throw new ArgumentException($"Null/blank {nameof(value)} specified");
    
            Value = value;
        }
        public string Value { get; }
    }
    then deserialising from JSON using the Bridge Newtonsoft package fails because it tries to call the constructor without passing any arguments - eg.

    var x = new MyString("abc");
    var json = JsonConvert.SerializeObject(x);
    var cloneX = JsonConvert.DeserializeObject<MyString>(json);
    If I try this with the .NET version of JSON.NET then the DeserialiseObject method calls the constructor with the correct "value" argument.

    #2
    Thanks for the report. We will investigate and fix.

    Comment


      #3
      I think that this is a variation on the theme - it's not exactly the same issue but it seemed sufficiently related that it was better to add it here than to create a separate case.

      JSON.NET will serialise types that implement IEnumerable<T> into an array and will deserialise back from a JSON array to the original type if the type has a public constructor that takes an IEnumerable<T> argument.

      To demonstrate, the following behaves differently in Bridge than in .NET -

      public static class Program
      {
          static void Main()
          {
              var list = new MyList<string>(new[] { "a", "b" });
              var json = JsonConvert.SerializeObject(list);
              var clone = JsonConvert.DeserializeObject<MyList<string>>(json);
      
              Console.WriteLine(list.ToArray());
              Console.WriteLine(json);
              Console.WriteLine(clone.ToArray());
          }
      }
      
      public sealed class MyList<T> : IEnumerable<T>
      {
          private readonly IEnumerable<T> _values;
          public MyList(IEnumerable<T> values)
          {
              _values = values;
          }
      
          public IEnumerator<T> GetEnumerator() { return _values.GetEnumerator(); }
          IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
      }
      In .NET, the output is this:

      Original list's values: a, b
      JSON: ["a","b"]
      Cloned list's values: a, b
      But in Bridge the output of the first two lines is:

      Original list's values: a, b
      JSON: {}
      and an exception is thrown by the third line:

      Uncaught TypeError: Cannot read property 'System$Collections$Generic$IEnumerable$1$System$S tring$getEnumerator' of undefined

      Comment


        #4
        Hi,

        Git issue: https://github.com/bridgedotnet/Brid....Json/issues/4

        Comment


          #5
          This issue has been fixed. Pull request has been submitted and is awaiting further review and testing before merging into the master branch.

          Comment


            #6
            Fix for issue #4 merged into Bridge.Newtonsoft.Json repo's master branch and will be included in the next Bridge.NET release.

            Comment

            Working...
            X