3

I need to serialize objects to JSON. If I install mono from apt-get, serializing with JSON.net does not work.

I added this line into /etc/apt/sources.list:

deb http://debian.meebey.net/experimental/mono /

After this, i ran

sudo apt-get clean
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install mono-complete

This version of mono supports serializing into JSON. If you dont add the line into sources.list, all serializations will fail, not only those with double values. When I have a double in a dictionary or in a list, this exception always gets thrown thy JSON.net.

Input string was not in the correct format

Here is some sample code, so you can try (you need to add a reference to JSON.net):

try { Console.WriteLine(3.14159265359f.ToString()); } catch (Exception ex) { Console.WriteLine(ex.Message); }
try { Console.WriteLine(3.14159265359d.ToString()); } catch (Exception ex) { Console.WriteLine(ex.Message); }
try { Console.WriteLine(Convert.ToDouble("3.14159265359").ToString()); } catch (Exception ex) { Console.WriteLine(ex.Message); }
try { Console.WriteLine(Convert.ToDouble("3,14159265359").ToString()); } catch (Exception ex) { Console.WriteLine(ex.Message); }
try { Console.WriteLine(JsonConvert.SerializeObject(3.14159265359f)); } catch (Exception ex) { Console.WriteLine(ex.Message); }
try { Console.WriteLine(JsonConvert.SerializeObject(3.14159265359d)); } catch (Exception ex) { Console.WriteLine(ex.Message); }
try { Console.WriteLine(JsonConvert.SerializeObject(new List<object>() { "test", DateTime.Now, 3.14159265359f, 3.14159265359d})); } catch (Exception ex) { Console.WriteLine(ex.Message); }
try { Console.WriteLine(JsonConvert.SerializeObject(new Dictionary<object, object>() {
    {"test", DateTime.Now},
    {DateTime.Now, 3.14159265359f},
    {3.14159265359f, 3.14159265359d},
    {3.14159265359d, "test"},
})); } catch (Exception ex) { Console.WriteLine(ex.Message); }

In my case, this results in

3,141593
3,14159265359
314159265359
Input string was not in the correct format
Input string was not in the correct format
Input string was not in the correct format
Input string was not in the correct format
Input string was not in the correct format

I need to serialize and dictionary or an object where some properties are double numbers, but I dont know how to fix this error.

feedc0de
  • 229
  • 2
  • 3
  • 9

1 Answers1

2

This works for me on my Pi. I'm using a version of Mono that I compiled back in December before the patch for hard-float and Mono was released. Here's the output I get. I suspect that the issue has to do with the internationalization of the decimal point character.

Here is the output of mono --version:

Mono Runtime Engine version 3.2.7 (master/e42840f Thu Dec  5 11:31:03 EST 2013)
Copyright (C) 2002-2013 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       normal
        Notifications: epoll
        Architecture:  armel,vfp+hard
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

I also manually downloaded Json.net and specifically referenced the NET20 dll.

johnma@raspberrypi ~/tpf$ $ mcs -r:Newtonsoft.Json.dll jsontest.cs
johnma@raspberrypi ~/tpf$ $ ./jsontest.exe
NumberFormatInfo.NumberDecimalSeparator = .
3.141593
3.14159265359
3.14159265359
314159265359
3.14159274
3.14159265359
["test","2014-04-11T16:32:29.975495-04:00",3.14159274,3.14159265359]
{"test":"2014-04-11T16:32:30.971131-04:00","00/735334/0001 16:32:30":3.14159274,"3.141593":3.14159265359,"3.14159265359":"test"}

Update: Success! I've recreated your problem!

I get your results when I run jsontest.exe using LANG=de_DE.UTF-8, see below:

johnma@raspberrypi ~/tpf$ $ LANG=de_DE.UTF-8 ./jsontest.exe
CultureInfo.CurrentCulture = de-DE
NumberFormatInfo.NumberDecimalSeparator = ,
3,141593
3,14159265359
314159265359
Input string was not in the correct format
Input string was not in the correct format
Input string was not in the correct format
Input string was not in the correct format
Input string was not in the correct format

I suspect that this is most likely a bug or quirk in Mono. Clearly Convert.ToDouble("3,14159265359") is throwing an exception. I suspect that all other exceptions are due to the Double values being stored internally as String objects.

Can you run your exe using LANG=en_US.UTF-8?

Here's the source I compiled:

using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Globalization;

class MainClass
{
    public static void Main (string[] args)
    {
        Console.WriteLine( "CultureInfo.CurrentCulture = "
                           + CultureInfo.CurrentCulture );
        NumberFormatInfo nfi = NumberFormatInfo.GetInstance(CultureInfo.CurrentCulture);
        Console.WriteLine( "NumberFormatInfo.NumberDecimalSeparator = "
                           + nfi.NumberDecimalSeparator );
        try { Console.WriteLine(3.14159265359f.ToString()); }
        catch (Exception ex) { Console.WriteLine(ex.Message); }

        try { Console.WriteLine(3.14159265359d.ToString()); }
        catch (Exception ex) { Console.WriteLine(ex.Message); }

        try { Console.WriteLine(Convert.ToDouble("3.14159265359").ToString()); }
        catch (Exception ex) { Console.WriteLine(ex.Message); }

        try { Console.WriteLine(Convert.ToDouble("3,14159265359").ToString()); }
        catch (Exception ex) { Console.WriteLine(ex.Message); }

        try { Console.WriteLine(JsonConvert.SerializeObject(3.14159265359f)); }
        catch (Exception ex) { Console.WriteLine(ex.Message); }

        try { Console.WriteLine(JsonConvert.SerializeObject(3.14159265359d)); }
        catch (Exception ex) { Console.WriteLine(ex.Message); }

        try { Console.WriteLine(JsonConvert.SerializeObject(new List<object>() {
            "test", DateTime.Now, 3.14159265359f, 3.14159265359d})); }
        catch (Exception ex) { Console.WriteLine(ex.Message); }

        try { Console.WriteLine(JsonConvert.SerializeObject(new Dictionary<object, object>() {
            {"test", DateTime.Now},
            {DateTime.Now, 3.14159265359f},
            {3.14159265359f, 3.14159265359d},
            {3.14159265359d, "test"},
        })); }
        catch (Exception ex) { Console.WriteLine(ex.Message); }
    }
}

Updated to add code to display NumberFormatInfo.NumberDecimalSeparator

HeatfanJohn
  • 3,115
  • 3
  • 26
  • 38