简体   繁体   中英

Null problem when (de)serializing multiple objects with json

[SOLVED] applied given solution, works fine!

Aim of the program: Save/reload previous data when user opens and closes the program.

I used to (de)serialize successfully with one object ( obj ), now I have two different objects of different classes.

I tried to combine them by looking at other posts; I put them in object array and give that object array when (de)serializing as parameter.

I do initialize for example like this; obj.flag1 = true; before calling serialize() in other methods.(I didn't put them for simplicity since I already stated the functionality of methods)

It says objects are null, but logically if obj2 and obj were null, it should have given the error for obj standalone. It won't read empty file I handled it. The moment I tried to combine two object it started to give me null error for both of them. I am about to rip my hair, can someone please help?

 [Serializable]
    public partial class UI : Form
    {
        FlagClass obj;
        CurrentAmplitude obj2;

        object[] seri_obj;//combine multiple objects

        //deserialization is performed in constructor
        public UI()
        {

            InitializeComponent();

            seri_obj = new object[] { obj, obj2 };

            input += ".txt";

            //default path + new filename
            path_combined = Path.Combine(root, input);

            //it won't try to read empty file
            if (!File.Exists(path_combined))
            {

                using (var stream = File.Create(path_combined))
                {

                }

            }
            else //already have that file,so when user opens the program, data is loaded from file
            {
                //read booleans and inetegres

                string json2 = File.ReadAllText(path_combined);
                string FormattedJson = FormatJson(json2);
                seri_obj = JsonConvert.DeserializeObject<object[]>(FormattedJson);

            }
        }


        private static string FormatJson(string json)
        {
            dynamic parsedJson = JsonConvert.DeserializeObject(json);
            return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
        }

        //I do serialization here
        void Serialize()
        {
            string json = JsonConvert.SerializeObject(seri_obj, Formatting.Indented);
            File.WriteAllText(path_combined, json);

        }

String values are in this class via "obj2"

[Serializable]
    class CurrentAmplitude
    {
    //this class has the string values
        [JsonProperty(PropertyName = "value1")]
        public int value1 { get; set; }

        [JsonProperty(PropertyName = "value2")]
        public string value2 { get; set; }

        [JsonProperty(PropertyName = "value3")]
        public string value3 { get; set; }

        [JsonProperty(PropertyName = "value4")]
        public string value4 { get; set; }

        [JsonProperty(PropertyName = "value5")]
        public string value5 { get; set; }


        public CurrentAmplitude(){

        }
    }

Boolean values are in this class via "obj"

[Serializable]
    class FlagClass
    {
    //this class has the boolean values
        [JsonProperty(PropertyName = "flag1")]
        public bool flag1 { get; set; }

        [JsonProperty(PropertyName = "flag2")]
        public bool flag2 { get; set; }

        public FlagClass()
        { 

        }

    }

空对象警告

Where you are deserializing:-

seri_obj = JsonConvert.DeserializeObject<object[]>(FormattedJson);

You are asking the deserializer to return an array raw objects, which will result in an array of JObject types, not your FlagClass and CurrentAmplitude types.

You're also setting seri_obj , but never assigning the values in seri_obj to your obj or obj2 variables, which is why the compiler is warning you.

You would be better off having an umbrella configuration class like this:-

class Configuration
{
    public Flag { get; set; } = new FlagClass();

    public CurrentAmplitude { get; set; } = new CurrentAmplitude();
}

Then just deserialize/serialize an instance of your Configuration class when you want to load/save...

// create config object if new
var config = new Configuration();

// to save
var json = JsonConvert.SerializeObject(config);

// to load
var config = JsonConvert.DeserializeObject<Configuration>(json);

// get/set config values
config.Flag.flag2 = false;

Here is a more complete example:-

void Main()
{
    // create a new blank configuration
    Configuration config = new Configuration();

    // make changes to the configuration
    config.CurrentAmplitude.value1 = 123;
    config.CurrentAmplitude.value2 = "Hello";
    config.FlagClass.flag1 = false;
    config.FlagClass.flag2 = true;

    // serialize configuration to a string in order to save to a file
    string json = JsonConvert.SerializeObject(config);

    // reload config from saved string
    config = JsonConvert.DeserializeObject<Configuration>(json);

    // should print "Hello"
    Console.WriteLine(config.CurrentAmplitude.value2);
}

class Configuration
{
    public CurrentAmplitude CurrentAmplitude { get; set; } = new CurrentAmplitude();

    public FlagClass FlagClass { get; set; } = new FlagClass();
}

class CurrentAmplitude
{
    public int value1 { get; set; }

    public string value2 { get; set; }

    public string value3 { get; set; }

    public string value4 { get; set; }

    public string value5 { get; set; }
}

class FlagClass
{
    public bool flag1 { get; set; }

    public bool flag2 { get; set; }
}

Pre C# 6, your config class would look like this:-

class Configuration
{
    public Configuration()
    {
        CurrentAmplitude = new CurrentAmplitude();
        FlagClass = new FlagClass();
    }

    public CurrentAmplitude CurrentAmplitude { get; set; }

    public FlagClass FlagClass { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM