diff --git a/src/Docker.DotNet/QueryString.cs b/src/Docker.DotNet/QueryString.cs index 74323ef9..735d5971 100644 --- a/src/Docker.DotNet/QueryString.cs +++ b/src/Docker.DotNet/QueryString.cs @@ -21,46 +21,48 @@ public QueryString(T value) AttributedPublicProperties = FindAttributedPublicProperties(); } - public IDictionary GetKeyValuePairs() + /// + /// Returns formatted query string. + /// + /// + public string GetQueryString() { - var queryParameters = new Dictionary(); - foreach (var pair in AttributedPublicProperties) + var queryStringBuilder = new StringBuilder(); + + foreach (var attributedProperty in AttributedPublicProperties) { - var property = pair.Key; - var attribute = pair.Value; + var property = attributedProperty.Key; + var attribute = attributedProperty.Value; + var value = property.GetValue(Object, null); // 'Required' check if (attribute.IsRequired && value == null) { - string propertyFullName = $"{property.DeclaringType?.FullName}.{property.Name}"; + var propertyFullName = $"{property.DeclaringType?.FullName}.{property.Name}"; throw new ArgumentException("Got null/unset value for a required query parameter.", propertyFullName); } - // Serialize + // Serialization if (attribute.IsRequired || !IsDefaultOfType(value)) { - var keyStr = attribute.Name; - var valueStr = attribute.Convert(value!); + var queryParameterName = attribute.Name; - queryParameters[keyStr] = valueStr; + foreach (var queryParameterValue in attribute.Convert(value!)) + { + if (queryStringBuilder.Length > 0) + { + queryStringBuilder.Append('&'); + } + + queryStringBuilder.Append(Uri.EscapeDataString(queryParameterName)); + queryStringBuilder.Append('='); + queryStringBuilder.Append(Uri.EscapeDataString(queryParameterValue)); + } } } - return queryParameters; - } - - /// - /// Returns formatted query string. - /// - /// - public string GetQueryString() - { - return string.Join("&", - GetKeyValuePairs().Select( - pair => string.Join("&", - pair.Value.Select( - v => $"{Uri.EscapeDataString(pair.Key)}={Uri.EscapeDataString(v)}")))); + return queryStringBuilder.ToString(); } private static Dictionary FindAttributedPublicProperties< diff --git a/src/Docker.DotNet/QueryStringBoolParameterAttribute.cs b/src/Docker.DotNet/QueryStringBoolParameterAttribute.cs index 368b497f..836f030a 100644 --- a/src/Docker.DotNet/QueryStringBoolParameterAttribute.cs +++ b/src/Docker.DotNet/QueryStringBoolParameterAttribute.cs @@ -2,7 +2,7 @@ namespace Docker.DotNet; internal sealed class QueryStringBoolParameterAttribute(string name, bool required) : QueryStringParameterAttribute(name, required) { - public override string[] Convert(object value) + public override IEnumerable Convert(object value) { Debug.Assert(value != null); diff --git a/src/Docker.DotNet/QueryStringListParameterAttribute.cs b/src/Docker.DotNet/QueryStringListParameterAttribute.cs index 16e130f4..f71c133f 100644 --- a/src/Docker.DotNet/QueryStringListParameterAttribute.cs +++ b/src/Docker.DotNet/QueryStringListParameterAttribute.cs @@ -2,7 +2,7 @@ namespace Docker.DotNet; internal sealed class QueryStringListParameterAttribute(string name, bool required) : QueryStringParameterAttribute(name, required) { - public override string[] Convert(object value) + public override IEnumerable Convert(object value) { Debug.Assert(value != null); Debug.Assert(value is IList); @@ -12,6 +12,6 @@ public override string[] Convert(object value) throw new ArgumentException($"Expected value of type '{typeof(IList)}'.", nameof(value)); } - return typedValue.ToArray(); + return typedValue; } } \ No newline at end of file diff --git a/src/Docker.DotNet/QueryStringMapParameterAttribute.cs b/src/Docker.DotNet/QueryStringMapParameterAttribute.cs index c8fc3933..5fa1f4bb 100644 --- a/src/Docker.DotNet/QueryStringMapParameterAttribute.cs +++ b/src/Docker.DotNet/QueryStringMapParameterAttribute.cs @@ -2,7 +2,7 @@ namespace Docker.DotNet; internal sealed class QueryStringMapParameterAttribute(string name, bool required) : QueryStringParameterAttribute(name, required) { - public override string[] Convert(object value) + public override IEnumerable Convert(object value) { Debug.Assert(value != null); Debug.Assert(value is T); diff --git a/src/Docker.DotNet/QueryStringParameterAttribute.cs b/src/Docker.DotNet/QueryStringParameterAttribute.cs index 11032a6b..8090e2b3 100644 --- a/src/Docker.DotNet/QueryStringParameterAttribute.cs +++ b/src/Docker.DotNet/QueryStringParameterAttribute.cs @@ -7,7 +7,7 @@ internal class QueryStringParameterAttribute : Attribute public bool IsRequired { get; private set; } - public virtual string[] Convert(object value) => [value.ToString()!]; + public virtual IEnumerable Convert(object value) => [value.ToString()!]; public QueryStringParameterAttribute(string name, bool required) {