C
C#2y ago
kyeede

❔ Implement New Class to JSON with Default Values

Hello, I have a class as followed:
public class CommandModuleRoot
{
public List<GuildModulesConfiguration> GuildModulesConfiguration { get; set; }
}

public class GuildModulesConfiguration
{
public ModuleCaseSystem ModuleCaseSystem { get; set; }
}

public class ModuleCaseSystem
{
public int ModuleID { get; set; }
public string ModuleName { get; set; }
public bool ModuleIsActive{ get; set; }

[Description("Sets the channel where cases are automatically or manually created regardless in which channel the command was executed in.")]
public ulong GuildAutoPostChannel { get; set; }

[Description("Determines whether the user will be notified about any cases created for them. This also includes modifications to the case such as updates.")]
public bool EnableUserCaseNotifications { get; set; }
}
public class CommandModuleRoot
{
public List<GuildModulesConfiguration> GuildModulesConfiguration { get; set; }
}

public class GuildModulesConfiguration
{
public ModuleCaseSystem ModuleCaseSystem { get; set; }
}

public class ModuleCaseSystem
{
public int ModuleID { get; set; }
public string ModuleName { get; set; }
public bool ModuleIsActive{ get; set; }

[Description("Sets the channel where cases are automatically or manually created regardless in which channel the command was executed in.")]
public ulong GuildAutoPostChannel { get; set; }

[Description("Determines whether the user will be notified about any cases created for them. This also includes modifications to the case such as updates.")]
public bool EnableUserCaseNotifications { get; set; }
}
Which returns:
{
"ModuleCaseSystem": {
"ModuleID": 1,
"ModuleName": "CaseSystem",
"ModuleIsActive": false,
"GuildAutoPostChannel": 0,
"EnableUserCaseNotifications": false
}
}
{
"ModuleCaseSystem": {
"ModuleID": 1,
"ModuleName": "CaseSystem",
"ModuleIsActive": false,
"GuildAutoPostChannel": 0,
"EnableUserCaseNotifications": false
}
}
Now, let's say I add a new class to GuildModulesConfiguration which would looks like this:
public class GuildModulesConfiguration
{
public ModuleCaseSystem ModuleCaseSystem { get; set; }
public NewModuleTest NewModuleTest { get; set; }
}

public class NewModuleTest
{
public int ModuleID { get; set; } = 2;
public string ModuleName { get; set; } = "Test";
public bool ModuleIsActive { get; set; } = false;
}
public class GuildModulesConfiguration
{
public ModuleCaseSystem ModuleCaseSystem { get; set; }
public NewModuleTest NewModuleTest { get; set; }
}

public class NewModuleTest
{
public int ModuleID { get; set; } = 2;
public string ModuleName { get; set; } = "Test";
public bool ModuleIsActive { get; set; } = false;
}
Whenever I try to deserialize and serialize the JSON file, it adds the new class as null without any values.
{
"ModuleCaseSystem": {
"ModuleID": 1,
"ModuleName": "CaseSystem",
"ModuleIsActive": false,
"GuildAutoPostChannel": 0,
"EnableUserCaseNotifications": false
},
"NewModuleTest": null
}
{
"ModuleCaseSystem": {
"ModuleID": 1,
"ModuleName": "CaseSystem",
"ModuleIsActive": false,
"GuildAutoPostChannel": 0,
"EnableUserCaseNotifications": false
},
"NewModuleTest": null
}
What I want to achieve is this:
{
"ModuleCaseSystem": {
"ModuleID": 1,
"ModuleName": "CaseSystem",
"ModuleIsActive": false,
"GuildAutoPostChannel": 0,
"EnableUserCaseNotifications": false
},
"NewModuleTest": {
"ModuleID": 2,
"ModuleName": "Test",
"ModuleIsActive": true
}
}
{
"ModuleCaseSystem": {
"ModuleID": 1,
"ModuleName": "CaseSystem",
"ModuleIsActive": false,
"GuildAutoPostChannel": 0,
"EnableUserCaseNotifications": false
},
"NewModuleTest": {
"ModuleID": 2,
"ModuleName": "Test",
"ModuleIsActive": true
}
}
Any ideas what I could possibly do? CryingMan
27 Replies
Angius
Angius2y ago
It seems you never instantiate that class And a default value of a reference type is null
kyeede
kyeedeOP2y ago
How would I go about instantiating it?
Angius
Angius2y ago
Like any other class
kyeede
kyeedeOP2y ago
My code would be this:
var GetGuildModules = File.ReadAllText(GuildPath);
var GuildModules = JsonConvert.DeserializeObject<GuildModulesConfiguration>(GetGuildModules);

var UpdateGuildModules = JsonConvert.SerializeObject(GuildModules, Formatting.Indented);
File.WriteAllText(GuildPath, UpdateGuildModules);
var GetGuildModules = File.ReadAllText(GuildPath);
var GuildModules = JsonConvert.DeserializeObject<GuildModulesConfiguration>(GetGuildModules);

var UpdateGuildModules = JsonConvert.SerializeObject(GuildModules, Formatting.Indented);
File.WriteAllText(GuildPath, UpdateGuildModules);
Angius
Angius2y ago
Ah, well, if the JSON you're deserializing doesn't have the data you want... it won't have that data
kyeede
kyeedeOP2y ago
I check if the modules.json file exists, and if not, it creates this result:
c{
"ModuleCaseSystem": {
"ModuleID": 1,
"ModuleName": "CaseSystem",
"ModuleIsActive": false,
"GuildAutoPostChannel": 0,
"EnableUserCaseNotifications": false
},
"NewModuleTest": {
"ModuleID": 2,
"ModuleName": "Test",
"ModuleIsActive": true
}
}
c{
"ModuleCaseSystem": {
"ModuleID": 1,
"ModuleName": "CaseSystem",
"ModuleIsActive": false,
"GuildAutoPostChannel": 0,
"EnableUserCaseNotifications": false
},
"NewModuleTest": {
"ModuleID": 2,
"ModuleName": "Test",
"ModuleIsActive": true
}
}
However, since json file depends on each guild, I don't wanna override their values back to default. I actually hoped that adding default values to each key would serialize it but I assume that I have to define those values before serializing them? I just don't know whether that will create the same instance over and over again.
Angius
Angius2y ago
Yes, adding default values will deserialize them
kyeede
kyeedeOP2y ago
So, this?
public class NewModuleTest
{
public int ModuleID { get; set; } = 2;
public string ModuleName { get; set; } = "Test";
public bool ModuleIsActive { get; set; } = false;
}
public class NewModuleTest
{
public int ModuleID { get; set; } = 2;
public string ModuleName { get; set; } = "Test";
public bool ModuleIsActive { get; set; } = false;
}
Angius
Angius2y ago
public class GuildModulesConfiguration
{
public ModuleCaseSystem ModuleCaseSystem { get; set; }
public NewModuleTest NewModuleTest { get; set; }
}
public class GuildModulesConfiguration
{
public ModuleCaseSystem ModuleCaseSystem { get; set; }
public NewModuleTest NewModuleTest { get; set; }
}
but neither property in this class has a default value
kyeede
kyeedeOP2y ago
ah I see, I know where you're heading with this.
Angius
Angius2y ago
Just initialize them with = new();
kyeede
kyeedeOP2y ago
I have to define those values within GuildModulesConfiguration rather than within their own class.
Angius
Angius2y ago
Assuming of course your C# version is high enough to support shorthand constructors Both
kyeede
kyeedeOP2y ago
public ModuleCaseSystem ModuleCaseSystem = new()
{
ModuleID = 2,
ModuleName = "Test",
ModuleIsActive = false
};
public ModuleCaseSystem ModuleCaseSystem = new()
{
ModuleID = 2,
ModuleName = "Test",
ModuleIsActive = false
};
sweat
MODiX
MODiX2y ago
Angius#1586
REPL Result: Success
using System.Text.Json;

class Foo {
public int Bar { get; set; } = 69;
public string Baz { get; set; } = "nice";
}

class Unga {
public Foo Foo { get; set; } = new();
public string Bunga { get; set; } = "henlo";
}

var u = new Unga();
JsonSerializer.Serialize(u)
using System.Text.Json;

class Foo {
public int Bar { get; set; } = 69;
public string Baz { get; set; } = "nice";
}

class Unga {
public Foo Foo { get; set; } = new();
public string Bunga { get; set; } = "henlo";
}

var u = new Unga();
JsonSerializer.Serialize(u)
Result: string
{"Foo":{"Bar":69,"Baz":"nice"},"Bunga":"henlo"}
{"Foo":{"Bar":69,"Baz":"nice"},"Bunga":"henlo"}
Compile: 605.717ms | Execution: 59.915ms | React with ❌ to remove this embed.
kyeede
kyeedeOP2y ago
ah I see
Angius
Angius2y ago
(as a side note, as you can see, Newtonsoft.Json isn't really needed nowadays)
kyeede
kyeedeOP2y ago
I do know about that Json.NET exists but I never go into it For some reason, i went with newtonsoft
Angius
Angius2y ago
Unless you're stuck with an outdated version of .NET, like working with Unity or some legacy projects, Newtonsoft won't give you anything that STJ won't Well, besides being slow Newtonsoft excels at being slow
kyeede
kyeedeOP2y ago
Since I pretty much used Newtonsoft majorly throughout this project, I'm not sure if switching to STJ will break most code assuming that the method names are different
Angius
Angius2y ago
Method names are different, yes
kyeede
kyeedeOP2y ago
I see, I tested your code above and defined the values and it seems like everything is working now. :D
Angius
Angius2y ago
Search-replace should handle most of it though Nice
kyeede
kyeedeOP2y ago
Thank you very much! ayatoboba will consider using STJ on new projects, I see that literally every code on Stackoverflow uses STJ
Angius
Angius2y ago
Yeah, as I said, no reason to use Newtonsoft in any new projects nowadays Hell, the creator of Newtonsoft, James Newton-King was hired by Microsoft to work on STJ lol
kyeede
kyeedeOP2y ago
oh lol
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server