106 lines
4.0 KiB
C#
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));
|
|
}
|
|
} |