Serializing and deserializing a ArrayList

Hello!

I am trying to serialize and deserialize a arraylist of objects. This object is called Pager and is defined as follows:

    public class Pager
    {
        public int ID { get; set; }
        public int RIC { get; set; }
        public string Name { get; set; }
        public string SerialNumber { get; set; }
    }

In a different class, I have made an Arraylist containing these Pagers.
I want to be able to save this list of pagers to my SD card as a JSON file and then read it back again.

I have been able to serialize the arraylist correctly by doing this:

var result = JsonConverter.Serialize(Pagers.ToArray()).ToString();

Now, however when I try to deserialize by running below code:

var bson = JsonConverter.Deserialize(result).ToBson();

Pager[] pagers = (Pager[]) JsonConverter.FromBson(bson, typeof(Pager[]));

I get this error:

#### Exception System.NullReferenceException - CLR_E_NULL_REFERENCE (1) ####
#### Message: 
#### GHIElectronics.TinyCLR.Data.Json.JsonConverter::PopulateObject [IP: 0013] ####
#### GHIElectronics.TinyCLR.Data.Json.JsonConverter::PopulateObject [IP: 036d] ####
#### GHIElectronics.TinyCLR.Data.Json.JsonConverter::FromBson [IP: 000d] ####
#### PagerServerV3._0.Files.PagerFile::AddPager [IP: 0032] ####
#### PagerServerV3._0.Program::Main [IP: 006a] ####
 Exception thrown: 'System.NullReferenceException' in GHIElectronics.TinyCLR.Data.Json.dll
An unhandled exception of type 'System.NullReferenceException' occurred in 
 GHIElectronics.TinyCLR.Data.Json.dll

I don’t know of a different way of deserializing my data. What am I doing wrong?

Also, is it possible to use something else than an arraylist? E.g. a normal C# list for example.

I would really appreciate if someone could help me out here.

https://docs.ghielectronics.com/software/tinyclr/tutorials/serialization.html

Thank you for your reply, but if you look at the code in the tutorial you sent and at mine, you see that they are practically the same.

I followed that tutorial, it’s what got me here in the first place.

Convert byte[] to string with Encoding.UTF8.GetBytes() and use DeserializeObject()

ToBson() FromBson() didnt work for me either.

public static byte[] Serialize(object data)
            {
                JToken json = JsonConverter.Serialize(data);
                string jsonString = json.ToString();
                byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString);
                return jsonBytes;
            }

    public static Pager Deserialize(byte[] data)
            {
                if (data.Length > 0)
                {
                    string byteString = Encoding.UTF8.GetString(data);
                    Pager pager = (Pager)JsonConverter.DeserializeObject(byteString, typeof(Pager));
                    return pager;
                }
                return null;
            }
1 Like

Thank you! With this code I was able to solve my problem.

What changed in 2.1 preview 4 this does not work anymore?

 #### Exception System.NullReferenceException - CLR_E_NULL_REFERENCE (4) ####
    #### Message: 
    #### System.AppDomain::CreateInstanceAndUnwrap [IP: 0013] ####
    #### GHIElectronics.TinyCLR.Data.Json.JsonConverter::DefaultInstanceFactory [IP: 008a] ####
    #### GHIElectronics.TinyCLR.Data.Json.JsonConverter::PopulateObject [IP: 0027] ####
    #### GHIElectronics.TinyCLR.Data.Json.JsonConverter::DeserializeObject [IP: 000c] ####

edit: 6 days ago, there is a mention that enums dont work
Json Deserialized example - TinyCLR OS - GHI Electronics’ Forums
but they worked in TinyCLR 2.0

edit2: tried without enum, only simple int, same error

@mcalsyn helped with some fixes. Any ideas Martin?

I’m not sure if my answer exactly matches your problem, but just yesterday I ported @mcalsyn ‘JSON round-trip’ example to TinyCLR v2.1.0 Preview 4. There was a change needed regarding ‘CreateInstance’
I was not successful with enum but didn’t try for a longer time.
-https://github.com/RoSchmi/JSON_for_TinyCLR)

Looking at your Pager type and the code, that’s pretty straightforward and would seem to be covered by the existing unit tests. Is that still representative of you code that is failing? I will try to construct a program with those snippets to see if I can repro the problem.

There was a change to support polymorphic types and it’s always possible that I broke something, but my unit tests (which include basic types, complex types, arrays, and polymorphic classes) did pass. If you have an instance factory, the signature changed.

This crash isn’t ringing any bells with me, but I will run some tests and see if I can reproduce the problem using your fn’s and Pager type.

I added the code from this thread and just ran the unit test program, with these new routines and a call to DoLucaPTest(), and got no failures. Can you provide a minimal example of the failing code? Was there some other data structure (like an ArrayList) involved?

EDIT: I see now that Darko is posting the problem. I (not unreasonably) assumed that the ‘this’ that Darko was referring to was the example code in this thread, though maybe some other code is involved. If there was some other code pattern involved, then I will need an example of the failure so that I can repro.

public class Pager
{
    public int ID { get; set; }
    public int RIC { get; set; }
    public string Name { get; set; }
    public string SerialNumber { get; set; }
}

    public static byte[] LucaP_Serialize(object data)
    {
        JToken json = JsonConverter.Serialize(data);
        string jsonString = json.ToString();
        byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString);
        return jsonBytes;
    }

    public static Pager LucaP_Deserialize(byte[] data)
    {
        if (data.Length > 0)
        {
            string byteString = Encoding.UTF8.GetString(data);
            Pager pager = (Pager)JsonConverter.DeserializeObject(byteString, typeof(Pager));
            return pager;
        }
        return null;
    }

    private static void DoLucaPTest()
    {
        var pager = new Pager
        {
            ID = 1,
            RIC = 2,
            Name = "foo",
            SerialNumber = "123",
        };

        var data = LucaP_Serialize(pager);
        var result = LucaP_Deserialize(data);

        if (result.ID != pager.ID ||
            result.RIC != pager.RIC ||
            result.Name != pager.Name ||
            result.SerialNumber != pager.SerialNumber)
        {
            throw new Exception("LucaP test failed");
        }
    }