From 06f9d0f382b9d84b563f421adda94e3771f12bf9 Mon Sep 17 00:00:00 2001 From: qschroter Date: Wed, 28 May 2025 12:41:37 +0200 Subject: [PATCH] add post as get middleware --- .github/workflows/publish-to-nuget.yml | 2 +- src/Bones.AspNetCore/Bones.AspNetCore.csproj | 14 ++++ src/Bones.AspNetCore/PostAsGetMiddleware.cs | 75 ++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/Bones.AspNetCore/Bones.AspNetCore.csproj create mode 100644 src/Bones.AspNetCore/PostAsGetMiddleware.cs diff --git a/.github/workflows/publish-to-nuget.yml b/.github/workflows/publish-to-nuget.yml index 23c283e..557316d 100644 --- a/.github/workflows/publish-to-nuget.yml +++ b/.github/workflows/publish-to-nuget.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - folder: [Bones, Bones.Akka, Bones.Converters, Bones.Flow, Bones.Grpc, Bones.Tests, Bones.X509, Bones.Akka.Monitoring, Bones.Monitoring] + folder: [Bones, Bones.Akka, Bones.AspNetCore, Bones.Converters, Bones.Flow, Bones.Grpc, Bones.Tests, Bones.X509, Bones.Akka.Monitoring, Bones.Monitoring] steps: # Checking out repository - name: Checkout 🛎️ diff --git a/src/Bones.AspNetCore/Bones.AspNetCore.csproj b/src/Bones.AspNetCore/Bones.AspNetCore.csproj new file mode 100644 index 0000000..b87c7f0 --- /dev/null +++ b/src/Bones.AspNetCore/Bones.AspNetCore.csproj @@ -0,0 +1,14 @@ + + + + + + + + net7.0 + $(VERSION) + dative-gpi + dative-gpi + + + diff --git a/src/Bones.AspNetCore/PostAsGetMiddleware.cs b/src/Bones.AspNetCore/PostAsGetMiddleware.cs new file mode 100644 index 0000000..b62a152 --- /dev/null +++ b/src/Bones.AspNetCore/PostAsGetMiddleware.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json; +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Primitives; + +using Bones.Monitoring.Core; + +namespace Bones.AspNetCore +{ + public class PostAsGetMiddleware : MonitoredMiddleware + { + public PostAsGetMiddleware( + IServiceProvider serviceProvider, + RequestDelegate next) : base(next, serviceProvider) + { + } + + protected override async Task HandleAsync(HttpContext context, RequestDelegate next) + { + if (context.Request.Method == "POST" + && context.Request.Query.ContainsKey("_method") + && context.Request.Query["_method"] == "GET" + && context.Request.HasJsonContentType()) + { + // Convert the request to a GET request + context.Request.Method = "GET"; + var doc = await JsonSerializer.DeserializeAsync>(context.Request.Body); + if (doc != null) + { + var props = Flat(doc); + var query = $"?{String.Join("&", props.Select(kv => $"{Uri.EscapeDataString(kv.Key)}={Uri.EscapeDataString(kv.Value)}"))}"; + context.Request.QueryString = new QueryString(query); + context.Request.Body = Stream.Null; + context.Request.ContentLength = 0; + } + } + await next(context); + return; + } + + private Dictionary Flat(Dictionary payload) + { + Dictionary result = new Dictionary(); + foreach (var item in payload) + { + var flatted = DeepFlat(item.Key, item.Value); + foreach (var flat in flatted) + { + result.Add(flat.Key, flat.Value); + } + } + return result; + } + + private IEnumerable> DeepFlat(string key, JsonElement value) + { + switch (value.ValueKind) + { + case JsonValueKind.Array when value.GetArrayLength() == 0: + return new[] { new KeyValuePair($"{key}[]", "") }; + case JsonValueKind.Array when value.GetArrayLength() != 0: + return value.EnumerateArray().SelectMany((item, index) => DeepFlat($"{key}[{index}]", item)); + case JsonValueKind.Object: + return value.EnumerateObject().SelectMany(prop => DeepFlat($"{key}.{prop.Name}", prop.Value)); + default: + return new[] { new KeyValuePair(key, value.ToString()) }; + } + } + } +}