using System.Globalization; using System.Text.Json.Serialization; using System.Text.Json; using System; using System.Text.RegularExpressions; namespace Kit.Helpers { using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Unicode; using System.Threading.Tasks; public static class JsonHelper { public static TObject? JsonDeserialize(this string json) { if (json == null || string.IsNullOrWhiteSpace(json)) return default(TObject); var options = new JsonSerializerOptions(); options.Converters.Add(new DateTimeIsoFormatConverter()); options.PropertyNameCaseInsensitive = true; return JsonSerializer.Deserialize(json, options); } public static string JsonSerialize(this TObject serializeObject, bool enableCyrillic = false, bool includeFields = false, bool writeIntended = false, JsonNamingPolicy? propertyNamingPolicy = null) { if (serializeObject == null) return "{}"; var options = new JsonSerializerOptions { IncludeFields = includeFields, Encoder = enableCyrillic ? JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic) : JavaScriptEncoder.Create(UnicodeRanges.BasicLatin), Converters = { new DateTimeIsoFormatConverter() }, WriteIndented = writeIntended, }; if (propertyNamingPolicy != null) { options.PropertyNamingPolicy = propertyNamingPolicy; } string result = JsonSerializer.Serialize(serializeObject, options); return result; } public static async Task JsonDeserialize(this Task task) { string json = await task.ConfigureAwait(false); return await Task.Run(() => json.JsonDeserialize()).ConfigureAwait(false); } } } public class DateTimeIsoFormatConverter : JsonConverter { private readonly string format = "yyyy-MM-ddTHH:mm"; public DateTimeIsoFormatConverter() { } public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { string item = reader.GetString(); if (DateTime.TryParseExact(item, this.format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out DateTime result)) { return result; } for (int i = 1; i < 10; i++) { string format_item = "yyyy-MM-ddTHH:mm:ss." + new string('f', i); if (DateTime.TryParseExact(item, format_item, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out DateTime result_item)) { return result_item; } if (DateTime.TryParseExact(item, format_item + "Z", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out result_item)) { return result_item; } if (DateTime.TryParseExact(item, format_item + "zzz", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out result_item)) { return result_item; } } Match match = Regex.Match(item, @"\/Date\((\d+)\)\/"); if (match.Success) { long milliseconds = long.Parse(match.Groups[1].Value); return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(milliseconds); } throw new FormatException(); } public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { ArgumentNullException.ThrowIfNull(writer, nameof(writer)); writer.WriteStringValue(value .ToUniversalTime() .ToString( this.format, CultureInfo.InvariantCulture)); } }