diff --git a/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs b/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs index 1da7a7750..96a79681d 100644 --- a/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs +++ b/src/modules/Elsa.Http/Activities/SendHttpRequestBase.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; using System.Net.Http.Headers; -using System.Threading.Tasks; using Elsa.Extensions; using Elsa.Http.ActivityOptionProviders; using Elsa.Http.ContentWriters; diff --git a/src/modules/Elsa.Http/Extensions/HttpActivityExecutionContextExtensions.cs b/src/modules/Elsa.Http/Extensions/HttpActivityExecutionContextExtensions.cs index c562a2e97..594691e17 100644 --- a/src/modules/Elsa.Http/Extensions/HttpActivityExecutionContextExtensions.cs +++ b/src/modules/Elsa.Http/Extensions/HttpActivityExecutionContextExtensions.cs @@ -1,9 +1,3 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Elsa.Http.Contracts; using Elsa.Workflows.Core; using Elsa.Workflows.Core.Models; @@ -20,7 +14,7 @@ internal static class HttpActivityExecutionContextExtensions if (contentParser == null) return null; - + return await contentParser.ReadAsync(content, returnType, cancellationToken); } @@ -28,19 +22,12 @@ internal static class HttpActivityExecutionContextExtensions { var value = context.Get(input.MemoryBlockReference()); - if (value is IDictionary dictionary1) - return dictionary1; - - if (value is IDictionary dictionary2) - return dictionary2.ToDictionary(x => x.Key, x => new[] { x.Value }); - - if (value is IDictionary dictionary3) - return dictionary3.ToDictionary( - pair => pair.Key, - pair => pair.Value is ICollection collection - ? collection.Select(x => x.ToString()!).ToArray() - : new[] { pair.Value.ToString()! }); - - return Array.Empty>(); + return value switch + { + IDictionary dictionary1 => dictionary1, + IDictionary dictionary2 => dictionary2.ToDictionary(x => x.Key, x => new[] { x.Value }), + IDictionary dictionary3 => dictionary3.ToDictionary(pair => pair.Key, pair => pair.Value is ICollection collection ? collection.Select(x => x.ToString()!).ToArray() : new[] { pair.Value.ToString()! }), + _ => Array.Empty>() + }; } } \ No newline at end of file diff --git a/src/modules/Elsa.Http/Models/HttpRequestHeaders.cs b/src/modules/Elsa.Http/Models/HttpRequestHeaders.cs index 08e63c5ce..0ac5e91e7 100644 --- a/src/modules/Elsa.Http/Models/HttpRequestHeaders.cs +++ b/src/modules/Elsa.Http/Models/HttpRequestHeaders.cs @@ -1,14 +1,17 @@ -using System.Collections.Generic; +using System.Text.Json.Serialization; using Elsa.Extensions; +using Elsa.Http.Serialization; namespace Elsa.Http.Models; +/// +/// Represents the headers of an HTTP request. +/// +[JsonConverter(typeof(HttpRequestHeadersConverter))] public class HttpRequestHeaders : Dictionary { - public string? ContentType => this.GetValue("content-type")?[0]; -} - -public class HttpResponseHeaders : Dictionary -{ + /// + /// Gets the content type of the request. + /// public string? ContentType => this.GetValue("content-type")?[0]; } \ No newline at end of file diff --git a/src/modules/Elsa.Http/Models/HttpResponseHeaders.cs b/src/modules/Elsa.Http/Models/HttpResponseHeaders.cs new file mode 100644 index 000000000..d93a43b36 --- /dev/null +++ b/src/modules/Elsa.Http/Models/HttpResponseHeaders.cs @@ -0,0 +1,14 @@ +using Elsa.Extensions; + +namespace Elsa.Http.Models; + +/// +/// Represents the headers of an HTTP response. +/// +public class HttpResponseHeaders : Dictionary +{ + /// + /// Gets the content type of the response. + /// + public string? ContentType => this.GetValue("content-type")?[0]; +} \ No newline at end of file diff --git a/src/modules/Elsa.Http/Serialization/HttpRequestHeadersConverter.cs b/src/modules/Elsa.Http/Serialization/HttpRequestHeadersConverter.cs new file mode 100644 index 000000000..840b2d6c4 --- /dev/null +++ b/src/modules/Elsa.Http/Serialization/HttpRequestHeadersConverter.cs @@ -0,0 +1,70 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using Elsa.Http.Models; + +namespace Elsa.Http.Serialization; + +/// +/// A custom JSON converter for that supports both single and multiple values. +/// +public class HttpRequestHeadersConverter : JsonConverter +{ + /// + public override HttpRequestHeaders Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Expected StartObject token"); + + var headers = new HttpRequestHeaders(); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + return headers; + + if (reader.TokenType != JsonTokenType.PropertyName) + throw new JsonException("Expected a PropertyName token"); + + var key = reader.GetString()!; + reader.Read(); + + // If the next token is not a StartArray token, then we expect a String token. + switch (reader.TokenType) + { + case JsonTokenType.StartArray: + { + var values = new List(); + while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) values.Add(reader.GetString()!); + headers.Add(key, values.ToArray()); + break; + } + case JsonTokenType.String: + { + var singleValue = reader.GetString()!; + headers.Add(key, new[] { singleValue }); + break; + } + default: + throw new JsonException("Expected a String or StartArray token"); + } + } + + throw new JsonException("Expected an EndObject token"); + } + + /// + public override void Write(Utf8JsonWriter writer, HttpRequestHeaders value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + + foreach (var header in value) + { + writer.WritePropertyName(header.Key); + writer.WriteStartArray(); + foreach (var headerValue in header.Value) writer.WriteStringValue(headerValue); + writer.WriteEndArray(); + } + + writer.WriteEndObject(); + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Http/Serialization/HttpStatusCodeCaseForWorkflowInstanceConverter.cs b/src/modules/Elsa.Http/Serialization/HttpStatusCodeCaseForWorkflowInstanceConverter.cs index 9547c1f69..8ad36ada0 100644 --- a/src/modules/Elsa.Http/Serialization/HttpStatusCodeCaseForWorkflowInstanceConverter.cs +++ b/src/modules/Elsa.Http/Serialization/HttpStatusCodeCaseForWorkflowInstanceConverter.cs @@ -1,4 +1,3 @@ -using System; using System.Text.Json; using System.Text.Json.Serialization; using Elsa.Http.Models;