From 13db083891900850f52dbeecaa5f6a9774e8ed5f Mon Sep 17 00:00:00 2001 From: DaPi Date: Wed, 21 Aug 2024 20:17:26 +0200 Subject: [PATCH] Problem with Empty Json Cannot create Object, when zeit_total_daily is empty --- Jugenddienst Stunden/Models/Hours.cs | 7 +- .../Models/JsonSingleOrEmptyArrayConverter.cs | 70 +++++++++++++++++++ .../ViewModels/StundenViewModel.cs | 8 ++- 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 Jugenddienst Stunden/Models/JsonSingleOrEmptyArrayConverter.cs diff --git a/Jugenddienst Stunden/Models/Hours.cs b/Jugenddienst Stunden/Models/Hours.cs index 765100b..f78bede 100644 --- a/Jugenddienst Stunden/Models/Hours.cs +++ b/Jugenddienst Stunden/Models/Hours.cs @@ -1,5 +1,6 @@  using CommunityToolkit.Mvvm.ComponentModel; +using Newtonsoft.Json; namespace Jugenddienst_Stunden.Models { public class Hours : ObservableObject { @@ -9,7 +10,11 @@ namespace Jugenddienst_Stunden.Models { public Dictionary nominal_week_api; //public List time_line; public string zeit_total; - public Dictionary? zeit_total_daily; + + //https://stackoverflow.com/questions/29449641/deserialize-json-when-a-value-can-be-an-object-or-an-empty-array/29450279#29450279 + + [JsonConverter(typeof(JsonSingleOrEmptyArrayConverter))] + public Dictionary zeit_total_daily; //public List wochensumme; public string overtime_month; public string overtime; diff --git a/Jugenddienst Stunden/Models/JsonSingleOrEmptyArrayConverter.cs b/Jugenddienst Stunden/Models/JsonSingleOrEmptyArrayConverter.cs new file mode 100644 index 0000000..a70fae2 --- /dev/null +++ b/Jugenddienst Stunden/Models/JsonSingleOrEmptyArrayConverter.cs @@ -0,0 +1,70 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Jugenddienst_Stunden.Models { + public class JsonSingleOrEmptyArrayConverter : JsonConverter where T : class { + public override bool CanConvert(Type objectType) { + return typeof(T).IsAssignableFrom(objectType); + } + + public override bool CanWrite { get { return false; } } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { + var contract = serializer.ContractResolver.ResolveContract(objectType); + if (!(contract is Newtonsoft.Json.Serialization.JsonObjectContract || contract is Newtonsoft.Json.Serialization.JsonDictionaryContract)) { + throw new JsonSerializationException(string.Format("Unsupported objectType {0} at {1}.", objectType, reader.Path)); + } + + switch (reader.SkipComments().TokenType) { + case JsonToken.StartArray: { + int count = 0; + while (reader.Read()) { + switch (reader.TokenType) { + case JsonToken.Comment: + break; + case JsonToken.EndArray: + return existingValue; + default: { + count++; + if (count > 1) + throw new JsonSerializationException(string.Format("Too many objects at path {0}.", reader.Path)); + existingValue = existingValue ?? contract.DefaultCreator(); + serializer.Populate(reader, existingValue); + } + break; + } + } + // Should not come here. + throw new JsonSerializationException(string.Format("Unclosed array at path {0}.", reader.Path)); + } + + case JsonToken.Null: + return null; + + case JsonToken.StartObject: + existingValue = existingValue ?? contract.DefaultCreator(); + serializer.Populate(reader, existingValue); + return existingValue; + + default: + throw new InvalidOperationException("Unexpected token type " + reader.TokenType.ToString()); + } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { + throw new NotImplementedException(); + } + } + + public static partial class JsonExtensions { + public static JsonReader SkipComments(this JsonReader reader) { + while (reader.TokenType == JsonToken.Comment && reader.Read()) + ; + return reader; + } + } +} diff --git a/Jugenddienst Stunden/ViewModels/StundenViewModel.cs b/Jugenddienst Stunden/ViewModels/StundenViewModel.cs index 77bbb74..33b85fc 100644 --- a/Jugenddienst Stunden/ViewModels/StundenViewModel.cs +++ b/Jugenddienst Stunden/ViewModels/StundenViewModel.cs @@ -34,6 +34,11 @@ namespace Jugenddienst_Stunden.ViewModels { public string OvertimeMonth { get => _hour.overtime_month; } + + public Dictionary ZeitTotalDaily { + get => _hour.zeit_total_daily; + } + public string Title { get; set; } = Preferences.Default.Get("name", "") + " " + Preferences.Default.Get("surname", ""); public StundenViewModel() { @@ -46,7 +51,7 @@ namespace Jugenddienst_Stunden.ViewModels { public async Task LoadData() { _hour = await Models.Stunde.LoadData(); - Models.Hours Hours = new Models.Hours(); + //Models.Hours Hours = new Models.Hours(); //Title = _hour.operator_api.name + " " + _hour.operator_api.surname; RefreshProperties(); } @@ -59,6 +64,7 @@ namespace Jugenddienst_Stunden.ViewModels { OnPropertyChanged(nameof(ZeitDone)); OnPropertyChanged(nameof(Hours)); OnPropertyChanged(nameof(Title)); + OnPropertyChanged(nameof(ZeitTotalDaily)); }