C
C#16mo ago
Kye

❔ 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
Angius16mo ago
It seems you never instantiate that class And a default value of a reference type is null
Kye
Kye16mo ago
How would I go about instantiating it?
Angius
Angius16mo ago
Like any other class
Kye
Kye16mo 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
Angius16mo ago
Ah, well, if the JSON you're deserializing doesn't have the data you want... it won't have that data
Kye
Kye16mo 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
Angius16mo ago
Yes, adding default values will deserialize them
Kye
Kye16mo 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
Angius16mo 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
Kye
Kye16mo ago
ah I see, I know where you're heading with this.
Angius
Angius16mo ago
Just initialize them with = new();
Kye
Kye16mo ago
I have to define those values within GuildModulesConfiguration rather than within their own class.
Angius
Angius16mo ago
Assuming of course your C# version is high enough to support shorthand constructors Both
Kye
Kye16mo ago
public ModuleCaseSystem ModuleCaseSystem = new()
{
ModuleID = 2,
ModuleName = "Test",
ModuleIsActive = false
};
public ModuleCaseSystem ModuleCaseSystem = new()
{
ModuleID = 2,
ModuleName = "Test",
ModuleIsActive = false
};
sweat
MODiX
MODiX16mo 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.
Kye
Kye16mo ago
ah I see
Angius
Angius16mo ago
(as a side note, as you can see, Newtonsoft.Json isn't really needed nowadays)
Kye
Kye16mo ago
I do know about that Json.NET exists but I never go into it For some reason, i went with newtonsoft
Angius
Angius16mo 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
Kye
Kye16mo 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
Angius16mo ago
Method names are different, yes
Kye
Kye16mo ago
I see, I tested your code above and defined the values and it seems like everything is working now. :D
Angius
Angius16mo ago
Search-replace should handle most of it though Nice
Kye
Kye16mo ago
Thank you very much! ayatoboba will consider using STJ on new projects, I see that literally every code on Stackoverflow uses STJ
Angius
Angius16mo 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
Kye
Kye16mo ago
oh lol
Accord
Accord16mo 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.