using System.Net; using System.Text; using System.Text.Json.Nodes; using Connected.Interop; using Microsoft.AspNetCore.Http; namespace Connected.Net; public static class HttpExtensions { private const string RequestArgumentsKey = "TP-REQUEST-ARGUMENTS"; public static async Task Deserialize(this HttpRequest request) { if (await ReadText(request) is not string text || string.IsNullOrWhiteSpace(text)) return default; if (JsonNode.Parse(text, new JsonNodeOptions { PropertyNameCaseInsensitive = true }) is not JsonNode node) return default; request.HttpContext.SetRequestArguments(node); return node; } public static async Task Deserialize(this HttpRequest request) { if (await ReadText(request) is not string text || string.IsNullOrWhiteSpace(text)) return default; return await Serializer.Deserialize(text); } private static async Task ReadText(HttpRequest request) { using var reader = new StreamReader(request.Body, Encoding.UTF8); return await reader.ReadToEndAsync(); } public static JsonNode? GetRequestArguments(this HttpContext context) { var result = context.Items[RequestArgumentsKey]; return result is null ? null : (JsonNode)result; } public static void SetRequestArguments(this HttpContext context, JsonNode arguments) { if (context is null) return; context.Items[RequestArgumentsKey] = arguments; } public static async Task Get(this IHttpService factory, string? requestUri, CancellationToken cancellationToken = default) { return await HandleResponse(await factory.CreateClient().SendAsync(CreateGetMessage(requestUri), cancellationToken)); } public static async Task Get(this IHttpService factory, string? requestUri, object content, CancellationToken cancellationToken = default) { return await HandleResponse(await factory.CreateClient().SendAsync(await CreateGetMessage(requestUri, content), cancellationToken)); } public static async Task Post(this IHttpService factory, string? requestUri, object? content, CancellationToken cancellationToken = default) { await HandleResponse(await factory.CreateClient().SendAsync(await CreatePostMessage(requestUri, content), cancellationToken)); } public static async Task Post(this IHttpService factory, string? requestUri, object? content, CancellationToken cancellationToken = default) { var client = factory.CreateClient(); var message = await CreatePostMessage(requestUri, content); var response = await client.SendAsync(message, cancellationToken); return await HandleResponse(response); } private static HttpRequestMessage CreateGetMessage(string? requestUri) { return new HttpRequestMessage(HttpMethod.Get, requestUri); } private static async Task CreateGetMessage(string? requestUri, object content) { return new HttpRequestMessage(HttpMethod.Get, requestUri) { Content = await CreateJsonContent(content) }; } private static async Task CreatePostMessage(string? requestUri, object? content) { return new HttpRequestMessage(HttpMethod.Post, requestUri) { Content = await CreateJsonContent(content) }; } private static async Task HandleResponse(HttpResponseMessage response) { if (!response.IsSuccessStatusCode) await HandleResponseException(response); } private static async Task HandleResponse(HttpResponseMessage response) { if (!response.IsSuccessStatusCode) await HandleResponseException(response); var content = response.Content.ReadAsStringAsync().Result; if (IsNull(content)) return default; return await Serializer.Deserialize(content); } private static async Task HandleResponseException(HttpResponseMessage response) { var ex = await ParseException(response.Content); if (ex is null) throw new WebException(response.ReasonPhrase); var source = string.Empty; var message = string.Empty; if (ex["source"] is JsonNode sourceNode) source = sourceNode.GetValue(); if (ex["message"] is JsonNode messageNode) message = messageNode.GetValue(); throw new WebException(message) { Source = source }; } private static async Task ParseException(HttpContent responseContent) { if (responseContent is null) return default; try { var rt = responseContent.ReadAsStringAsync().Result; return await Serializer.Deserialize(rt); } catch { return null; } } private static bool IsNull(string content) { return string.Equals(content, "null", StringComparison.OrdinalIgnoreCase) || string.IsNullOrWhiteSpace(content); } private static async Task CreateJsonContent(object? content) { if (content is null || Convert.IsDBNull(content)) return new StringContent(string.Empty); if (await Serializer.Serialize(content) is not string c) return new StringContent(string.Empty, Encoding.UTF8, "application/json"); return new StringContent(c, Encoding.UTF8, "application/json"); } }