Public properties and attributes are being nested into Non-public members

Fenrir88Fenrir88 Member ✭✭
edited April 2018 in Xamarin.Forms

Hi, I am working with an App on Xamarin.Forms that instances an object and saves it on a JSON file. I have the following classes

         [Serializable]
            public class CustomTask
            {
                public string collectionId { get; set; }
                public string taskId { get; set; }
                public int taskPosition { get; set; }
                public string taskName { get; set; }
                public int taskHours { get; set; }
                public int taskMinutes { get; set; }
                public int taskSeconds { get; set; }     
            }
         [Serializable]
            public class TaskCollection
            {
                public string collectionId { get; set; }
                public string collectionName { get; set; }
                public int collectionPosition { get; set; }
                public List<CustomTask> tasks { get; set; }

                public TaskCollection() { tasks = new List<CustomTask>(); }
            }

Then I call a method that creates an instance of TaskCollection for testing (which I made rather verbose for testing) :

    public TaskCollection getTC()
            {
                string colId= "Test ID";

                TaskCollection tc = new TaskCollection();
                tc.collectionId = colId;
                tc.collectionName = "Test Task Collection";
                tc.collectionPosition = 1;

                CustomTask ct1 = new CustomTask { collectionId = colId, taskHours = 1, taskId = "1", taskMinutes = 10, taskName = "First Task", taskPosition = 1, taskSeconds = 0 };
                CustomTask ct2 = new CustomTask { collectionId = colId, taskHours = 2, taskId = "2", taskMinutes = 12, taskName = "Second Task", taskPosition = 2, taskSeconds = 0 };
                CustomTask ct3 = new CustomTask { collectionId = colId, taskHours = 3, taskId = "3", taskMinutes = 13, taskName = "Third Task", taskPosition = 3, taskSeconds = 0 };
                CustomTask ct4 = new CustomTask { collectionId = colId, taskHours = 4, taskId = "4", taskMinutes = 14, taskName = "Fourth Task", taskPosition = 4, taskSeconds = 0 };

                List<CustomTask> list = new List<CustomTask>();
                list.Add(ct1);
                list.Add(ct2);
                list.Add(ct3);
                list.Add(ct4);

                tc.tasks = list;

                return tc;
            }

While Debugging I can see that all CustomTask and TaskCollection objects have all their properties under a Non-public members nest, and for each property an additional object called <"propety name">k_BackingField was created. For List list, the inspection shows a value of (null) right after being instantiated, yet it won't trigger a null reference during the Add calls. When it goes on to serialization and storage all it creates is an empty string, since everything became non-public.

I have tried using non automatic setters and getters, marking the class with [Newtonsoft.Json.JsonObject], and marking [DataContract] with [DataMember] on each property, changing the Linking options from None to SDK Assemblies Only to SDK and User. Also tried cleaning, rebuilding, restarting, and deleting obj and bin folders. Also tried creating new classes on new files, and changing targets Android API 23, 24, 25, and 26). None of these have worked.

My Xamarin version is 2.5.1.4449 and the project is a Xamarin.Forms Shared Project. I appreciate any new direction you might give me into making this simple data structure to be recognized properly. Thank you.

Update

Made a new Xamarin.Forms Project with .Net Standard, and ended up with the same results.

Also, I'm using Visual Studio 2017 (Version 15.6.6)

Answers

  • mwasimmwasim USMember ✭✭

    Hi @Fenrir88, do you want to generate JSON from your C# classes? You may try the tools below, here you may adjust your class code to your needs to generate the required JSON,

    http://csharp2json.io/

    However, if you already have example JSON data available, simply try the tool below, and it'll generate the C# classes for you,

    http://json2csharp.com/

  • Fenrir88Fenrir88 Member ✭✭
    edited April 2018

    Hi @mwasim, thank you for your answer. I used json2csharp to generate the C# classes and the outcome was:

    public class Task
    {
        public string collectionId { get; set; }
        public string taskId { get; set; }
        public int taskPosition { get; set; }
        public string taskName { get; set; }
        public int taskHours { get; set; }
        public int taskMinutes { get; set; }
        public int taskSeconds { get; set; }
    }
    
    public class RootObject
    {
        public string collectionId { get; set; }
        public string collectionName { get; set; }
        public int collectionPosition { get; set; }
        public List<Task> tasks { get; set; }
    }
    
    

    Which is pretty much the same structure. I have used those tools in the past to get the classes right when the problem is that the object from the Json deserialization leaves blank spots or similar. In this case I'd say the problem is that all the attributes from my classes are being removed from the public scope, so even before we get into serialization/deserialization the data is not reachable. I'll add an image of what I see during the debug session {My rookie status won't allow me to append the image but it still uploaded, so I'll add the link without the https} (hopefully it shows ok, this inspection is right at the return):

    In it we can see the object "tc" which is of TaskCollection Class. Despite all properties being public, we see no public properties. Instead we see a single "Non-public memebers" collections, where the properties for some reason ended up. Most of the data is there, with the exception of property "tasks" which is a List that ended up null despite being instanced with:

    tc.tasks = new List<CustomTask>();
    

    This also happens if instanced as a separate object. It seems that this happens to any List object.

    Image Link:

    us.v-cdn.net/5019960/uploads/editor/vx/ffkxvxop7jfn.png

    Update

    I have tried a couple of things that might bring me closer to finding the source of the problem. I have been deploying the app through Xamarin Live Player. I have tried with a Samsung Galaxy J7 Prime with Android 6 / API 23, and a Asus ZenPad 8 with Android 7 / API 25. Both presented the same problem.

    Then I used emulated devices, both API 23 and API 25, with x86 emulation. These work. When I ask to write the JSON on a label I properly see the data when deploying to the emulator. When I do the same on the real life devices through Xamarin Live all I get are empty curly brackets {}. --Therefore I think Xamarin Live Player might be the source of the issue.

    Update x2

    Changed to Release compiling, signed the APK and installed on one of my devices. It worked. Therefore the devices are not a source of the problem. Deploying through Xamarin Live keeps presenting the same problem.

  • Fenrir88Fenrir88 Member ✭✭
    edited April 2018

    Update x3

    After a some considerable effort I finally managed to get working the adb drivers, which was the reason that I wasn't debugging directly on my devices. Now I can tell that this method also works (the properties are perceived as public).

    I would say that the issue remains with Xamarin Live Player alone. Which, by the way, is updated to the latest version. This means I can continue with my development, however the issue still exists, and I really like the convenience of working with Xamarin Live Player. Therefore I'm still open to hearing possible solutions.

  • sameerssameers Member

    Hi Fenrir88, I am also facing same issue. If you come around any solution for Live Player, please do share.

  • sameerssameers Member

    Hi Fenrir88, I am also facing same issue. If you come around any solution for Live Player, please do share.

  • PaulMerricksPaulMerricks USMember

    Has there been any progress on this or it logged as a bug? I too am having the same issue when using the Live Player. I'm using 2017 v15.7.4 all up to date.

  • Fenrir88Fenrir88 Member ✭✭

    Hi. I'm afraid I didn't pursue this any further.

  • mchasemchase Member

    I fought and fought with this problem. It generally occurred with newly built classes. Obvious public class properties became non-public. Json failed to recognize them. Binding was lost. It came down to my Debug--Android Properties -- Android Options-- Linking. I had both Sdk and User Assemblies toggled on. I switched to just Sdk Assemblies Only and the bug disappeared. Turned on User Assemblies again, and bug was back. Turned it off, bug gone (obviously, after a rebuild). (Kudos to my brother for saying again and again, "It must be some weird setting".)

  • Fenrir88Fenrir88 Member ✭✭

    @mchase cool ! Now I'll have to try it out. Haven't used the app ever since. Will try it out this week.

Sign In or Register to comment.