Benutzer mit den meisten Antworten
Json Config-Datei für mehrere Klassen lesen (Newtonsoft.Json)

Frage
-
Hallo zusammen,
ich bastle grade an einem kleinen Tool, das ich mit einer Json-Datei Konfigurieren möchte.
Meine Json-Datei ist so aufgebaut, dass ich in einer json-Datei mehrere Objekte konfigurieren kann:
1. MainConfig
2. AusschussProzentConfigDiese beiden Objekte haben wiederum eigene Properties:
{ "MainConfig": { "MailHostOrIp": "192.168.120.10", "MailPort": 25, "MailFrom": "Automailer_AM@email.com", "MailFromDisplayName": "Info-Mailer", "UseCredentials": false, "UserName": "", "Password": "", "AutoClose": false }, "AusschussProzentConfig": { "EmailAktiv": true, "Mailto": [ "meineMail@email.de" ], "MailSubject": "[TLM] Artikelstamm - Ausschuss-Prozentsätze", "UpdateDb": true, "UpdateDbIfPercentLower": 30, "DaysToLookBack": 365, "HtmlTemplate": "AusschussProzent.html", "SqlQueryTemplate": "AusschussProzent.txt" } }
Ich habe mir zwei Klassen geschrieben: MainConfig und AusschussProzentConfig und möchte deren Properties nun gerne über
das Deserialisieren der json-Datei füllen. So sieht das für MainConfig aus:
[JsonObject("MainConfig")] class MainConfig { [JsonProperty("MailHostOrIp")] public string MailHostOrIp { get; set; } [JsonProperty("MailPort")] public int MailPort { get; set; } [JsonProperty("MailFrom")] public string MailFrom { get; set; } [JsonProperty("MailFromDisplayName")] public string MailFromDisplayName { get; set; } [JsonProperty("UseCredentials")] public bool UseCredentials { get; set; } [JsonProperty("UserName")] public string UserName { get; set; } [JsonProperty("Password")] public string Password { get; set; } [JsonProperty("AutoClose")] public bool AutoClose { get; set; } public static MainConfig GetMainConfig() { MainConfig _config = null; string jsonPath = Environment.CurrentDirectory + "\\MailerConfig.json"; if (HelperMethods.CheckJson() == true) { HelperMethods.ActionOutput("Lese Hauptkonfiguration."); var json = File.ReadAllText(jsonPath); _config = JsonConvert.DeserializeObject<MainConfig>(json); } return _config; } }
Wenn ich nun meine Methode GetMainConfig aufrufe, dann sind die Eigenschaften leider alle nicht gefüllt. Es gibt aber auch keine Fehlermeldung:
static void Main(string[] args) { var jso = MainConfig.GetMainConfig(); Console.WriteLine(jso.MailHostOrIp); Console.ReadKey(); }
Die gängigen Json-Online-Parser sagen alles ok.
Aber scheinbar kann der Deserializer die Objekte nicht finden und somit die Properties nicht zuweisen.
Könnt Ihr mir da helfen?
Danke, Patrick
Antworten
-
Hi,
entweder erstellst Du dir noch eine übergeordnete Klasse, die dann zwei Eigenschaften "MainConfig" und "AusschussProzentConfig" enthält oder Du musst aus der JSON Struktur nur die entsprechenden Nodes auswählen und diese einzeln deserialisieren.
Ich persönlich würde ersteres machen und die Logik aus dem Konstruktor entfernen. Sowas führt bei Fehlern oft dazu, dass man die eigentliche Problematik nur schwer erkennt. Wenn Du das so machen willst, dann lieber in einer eigenen Methode LoadConfig oder so ähnlich, die dann nach dem Erzeugen der Instanz aufgerufen wird (nicht aus dem Konstruktor heraus, sondern von außen).
Wenn Du letzteres machen willst, schau dich mal in der JSON.NET Doku um. Es gibt mehrere Wege, das Gewünschte zu erreichen.
https://www.newtonsoft.com/json/help/html/ParseJsonObject.htm
https://www.newtonsoft.com/json/help/html/QueryJson.htm
https://www.newtonsoft.com/json/help/html/QueryJsonSelectTokenWithLinq.htm
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert ppinbusiness Donnerstag, 14. September 2017 07:21
-
Hi,
der Grund ist recht einfach: Dein Objekt in der JSON Struktur heißt anders als die Eigenschaft der Klasse.
Genau hierfür gibt es auch das JsonProperty Attribut. Damit kann man abweichenende Namen festlegen.
In deinem Fall würde es helfen, wenn Du die Eigenschaft ausschussProzent anpasst.
[JsonProperty("AusschussProzentConfig")] public AusschussProzentConfig ausschussProzent { get; set; }
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert ppinbusiness Donnerstag, 14. September 2017 07:21
Alle Antworten
-
Hi,
entweder erstellst Du dir noch eine übergeordnete Klasse, die dann zwei Eigenschaften "MainConfig" und "AusschussProzentConfig" enthält oder Du musst aus der JSON Struktur nur die entsprechenden Nodes auswählen und diese einzeln deserialisieren.
Ich persönlich würde ersteres machen und die Logik aus dem Konstruktor entfernen. Sowas führt bei Fehlern oft dazu, dass man die eigentliche Problematik nur schwer erkennt. Wenn Du das so machen willst, dann lieber in einer eigenen Methode LoadConfig oder so ähnlich, die dann nach dem Erzeugen der Instanz aufgerufen wird (nicht aus dem Konstruktor heraus, sondern von außen).
Wenn Du letzteres machen willst, schau dich mal in der JSON.NET Doku um. Es gibt mehrere Wege, das Gewünschte zu erreichen.
https://www.newtonsoft.com/json/help/html/ParseJsonObject.htm
https://www.newtonsoft.com/json/help/html/QueryJson.htm
https://www.newtonsoft.com/json/help/html/QueryJsonSelectTokenWithLinq.htm
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert ppinbusiness Donnerstag, 14. September 2017 07:21
-
Hallo Stefan,
ich habe den Weg mit der zweiten Klasse eingeschlagen, aber wie genau muss läuft das dann mit dem DeSerialize ab?
Ich habe ein funktionierendes Beispiel wie folgt hinbekommen und kann auf die Eigenschaften von MainConfig zugreifen, nicht aber auf die von AusschussProzent. So habe ich das gemacht:
Nicht wundern, den Code bringe ich im nächsten Schritt ins reine. Das ist erst mal nur schnell getippert:class jsonMainConfigObjects { public MainConfig mainConfig { get; set; } public AusschussProzentConfig ausschussProzent { get; set; } } [JsonObject("MainConfig")] class MainConfig { [JsonProperty("MailHostOrIp")] public string MailHostOrIp { get; set; } [JsonProperty("MailPort")] public int MailPort { get; set; } [JsonProperty("MailFrom")] public string MailFrom { get; set; } [JsonProperty("MailFromDisplayName")] public string MailFromDisplayName { get; set; } [JsonProperty("UseCredentials")] public bool UseCredentials { get; set; } [JsonProperty("UserName")] public string UserName { get; set; } [JsonProperty("Password")] public string Password { get; set; } [JsonProperty("AutoClose")] public bool AutoClose { get; set; } } [JsonObject("AusschussProzentConfig")] class AusschussProzentConfig { [JsonProperty("EmailAktiv")] public bool EmailAktiv { get; set; } [JsonProperty("Mailto")] public string[] Mailto { get; set; } [JsonProperty("MailSubject")] public string MailSubject { get; set; } [JsonProperty("UpdateDb")] public bool UpdateDb { get; set; } [JsonProperty("UpdateDbIfPercentLower")] public double UpdateDbIfPercentLower { get; set; } [JsonProperty("DaysToLookBack")] public int DaysToLookBack { get; set; } [JsonProperty("HtmlTemplate")] public string HtmlTemplate { get; set; } [JsonProperty("SqlQueryTemplate")] public string SqlQueryTemplate { get; set; } }
class LoadConfig { public static jsonMainConfigObjects mConfig() { jsonMainConfigObjects r = new jsonMainConfigObjects(); string jsonPath = Environment.CurrentDirectory + "\\MailerConfig.json"; if (HelperMethods.CheckJson() == true) { HelperMethods.ActionOutput("Lese Hauptkonfiguration."); var json = File.ReadAllText(jsonPath); r = JsonConvert.DeserializeObject<jsonMainConfigObjects>(json); } return r; } }
Also die Werte von jso.mainConfig.xyz bekomme ich zurückgeliefert.
Aber bei jso.ausschussProzent.xyz gibt'sSystem.NullReferenceException: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."
- Bearbeitet ppinbusiness Donnerstag, 14. September 2017 06:55
-
Hi,
der Grund ist recht einfach: Dein Objekt in der JSON Struktur heißt anders als die Eigenschaft der Klasse.
Genau hierfür gibt es auch das JsonProperty Attribut. Damit kann man abweichenende Namen festlegen.
In deinem Fall würde es helfen, wenn Du die Eigenschaft ausschussProzent anpasst.
[JsonProperty("AusschussProzentConfig")] public AusschussProzentConfig ausschussProzent { get; set; }
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community- Als Antwort markiert ppinbusiness Donnerstag, 14. September 2017 07:21