Kit.Core/LibCommon/Kit.Core.Helpers/JsonHelper.cs

106 lines
4.0 KiB
C#

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<TObject>(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<TObject>(json, options);
}
public static string JsonSerialize<TObject>(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<TObject> JsonDeserialize<TObject>(this Task<string> task)
{
string json = await task.ConfigureAwait(false);
return await Task<TObject>.Run(() => json.JsonDeserialize<TObject>()).ConfigureAwait(false);
}
}
}
public class DateTimeIsoFormatConverter : JsonConverter<DateTime>
{
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));
}
}