diff options
Diffstat (limited to '')
-rw-r--r-- | LibMatrix/Extensions/HttpClientExtensions.cs | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/LibMatrix/Extensions/HttpClientExtensions.cs b/LibMatrix/Extensions/HttpClientExtensions.cs index 62e9a98..bffd74a 100644 --- a/LibMatrix/Extensions/HttpClientExtensions.cs +++ b/LibMatrix/Extensions/HttpClientExtensions.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Net.Http.Headers; using System.Reflection; using System.Text; @@ -26,6 +27,15 @@ public static class HttpClientExtensions { public class MatrixHttpClient : HttpClient { internal string? AssertedUserId { get; set; } + private JsonSerializerOptions GetJsonSerializerOptions(JsonSerializerOptions? options = null) { + options ??= new JsonSerializerOptions(); + options.Converters.Add(new JsonFloatStringConverter()); + options.Converters.Add(new JsonDoubleStringConverter()); + options.Converters.Add(new JsonDecimalStringConverter()); + options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; + return options; + } + public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request.RequestUri is null) throw new NullReferenceException("RequestUri is null"); @@ -68,7 +78,8 @@ public class MatrixHttpClient : HttpClient { } // GetFromJsonAsync - public async Task<T> GetFromJsonAsync<T>(string requestUri, CancellationToken cancellationToken = default) { + public async Task<T> GetFromJsonAsync<T>(string requestUri, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { + options = GetJsonSerializerOptions(options); var request = new HttpRequestMessage(HttpMethod.Get, requestUri); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await SendAsync(request, cancellationToken); @@ -82,7 +93,7 @@ public class MatrixHttpClient : HttpClient { Console.WriteLine("[!!] Checking sync response failed: " + e); } #endif - return await JsonSerializer.DeserializeAsync<T>(responseStream, cancellationToken: cancellationToken) ?? + return await JsonSerializer.DeserializeAsync<T>(responseStream, options, cancellationToken: cancellationToken) ?? throw new InvalidOperationException("Failed to deserialize response"); } @@ -97,19 +108,58 @@ public class MatrixHttpClient : HttpClient { public new async Task<HttpResponseMessage> PutAsJsonAsync<T>([StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, T value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { + options = GetJsonSerializerOptions(options); var request = new HttpRequestMessage(HttpMethod.Put, requestUri); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - request.Content = new StringContent(JsonSerializer.Serialize(value, value.GetType(), options ?? new() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }), + request.Content = new StringContent(JsonSerializer.Serialize(value, value.GetType(), options), Encoding.UTF8, "application/json"); return await SendAsync(request, cancellationToken); } public async Task<HttpResponseMessage> PostAsJsonAsync<T>([StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, T value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { + options ??= new(); + options.Converters.Add(new JsonFloatStringConverter()); + options.Converters.Add(new JsonDoubleStringConverter()); + options.Converters.Add(new JsonDecimalStringConverter()); + options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; var request = new HttpRequestMessage(HttpMethod.Post, requestUri); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - request.Content = new StringContent(JsonSerializer.Serialize(value, value.GetType(), options ?? new() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }), + request.Content = new StringContent(JsonSerializer.Serialize(value, value.GetType(), options), Encoding.UTF8, "application/json"); return await SendAsync(request, cancellationToken); } + + public async IAsyncEnumerable<T?> GetAsyncEnumerableFromJsonAsync<T>([StringSyntax(StringSyntaxAttribute.Uri)] string? requestUri, JsonSerializerOptions? options = null) { + options = GetJsonSerializerOptions(options); + var res = await GetAsync(requestUri); + var result = JsonSerializer.DeserializeAsyncEnumerable<T>(await res.Content.ReadAsStreamAsync(), options); + await foreach (var resp in result) { + yield return resp; + } + } +} + +public class JsonFloatStringConverter : JsonConverter<float> { + public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => float.Parse(reader.GetString()!); + + public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions options) + => writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture)); +} + +public class JsonDoubleStringConverter : JsonConverter<double> { + public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => double.Parse(reader.GetString()!); + + public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options) + => writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture)); +} + +public class JsonDecimalStringConverter : JsonConverter<decimal> { + public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => decimal.Parse(reader.GetString()!); + + public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options) + => writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture)); } |