Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Uri.EscapeDataString instead of HttpUtility.UrlEncode in Boilerplate (#9868) #9875

Merged
merged 5 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,7 @@ public static void AddTypedHttpClients(this IServiceCollection services)
internal class AppControllerBase
{{
System.Collections.Specialized.NameValueCollection queryString = HttpUtility.ParseQueryString(string.Empty);
public void AddQueryString(string existingQueryString)
{{
queryString.Add(HttpUtility.ParseQueryString(existingQueryString));
}}
AppQueryStringCollection queryString = [];
public void AddQueryString(string key, object? value)
{{
Expand All @@ -129,19 +124,12 @@ public void AddQueryStrings(Dictionary<string, object?> queryString)
protected string? GetDynamicQueryString()
{{
if (queryString is not {{ Count: > 0 }})
return null;
var collection = HttpUtility.ParseQueryString(string.Empty);
foreach (string key in queryString)
{{
collection.Add(key, queryString[key]);
}}
var result = queryString.ToString();
queryString.Clear();
return collection.ToString();
return result;
}}
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public string OrFilter

public override string ToString()
{
var qs = new Dictionary<string, string>();
var qs = new AppQueryStringCollection();

if (Top is not null)
{
Expand Down Expand Up @@ -65,7 +65,7 @@ public override string ToString()
qs.Add("$search", Search);
}

return string.Join('&', qs.Select(kv => $"{kv.Key}={kv.Value}"));
return qs.ToString();
}

public static implicit operator string(ODataQuery query) => query.ToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ namespace Boilerplate.Shared.Controllers
{
public interface IAppController
{
void AddQueryString(string existingQueryString) { }
void AddQueryString(string key, object? value) { }
void AddQueryStrings(Dictionary<string, object?> queryString) { }
}
Expand All @@ -17,8 +16,7 @@ public static class IAppControllerExtensions
public static TAppController WithQuery<TAppController>(this TAppController controller, string existingQueryString)
where TAppController : IAppController
{
controller.AddQueryString(existingQueryString);
return controller;
return controller.WithQuery(queryString: AppQueryStringCollection.Parse(existingQueryString));
}

public static TAppController WithQuery<TAppController>(this TAppController controller, string key, object? value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public static string GetUrlWithoutQueryParameter(this Uri uri, string key)

string pagePathWithoutQueryString = uri.GetLeftPart(UriPartial.Path);

return qsCollection.IsEmpty is false
return qsCollection is { Count: > 0 }
? $"{pagePathWithoutQueryString}?{qsCollection}"
: pagePathWithoutQueryString;
}
Expand All @@ -23,11 +23,9 @@ public static string GetUrlWithoutQueryParameter(this Uri uri, string key)
{
if (CultureInfoManager.MultilingualEnabled is false)
return null;

var culture = AppQueryStringCollection.Parse(uri.Query)["culture"];

if (string.IsNullOrEmpty(culture) is false)
return culture;
if (AppQueryStringCollection.Parse(uri.Query).TryGetValue("culture", out var culture))
return culture?.ToString();

foreach (var segment in uri.Segments.Take(2))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,11 @@ namespace System;
/// <summary>
/// An alternative to <see cref="HttpUtility.ParseQueryString(string)"/> that utilizes <see cref="Uri.EscapeDataString(string)"/> instead of <see cref="HttpUtility.UrlEncode(string?)"/>.
/// </summary>
public class AppQueryStringCollection
public class AppQueryStringCollection() : Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase)
{
private readonly Dictionary<string, string> keyValues = [];

public AppQueryStringCollection Add(string key, string? value)
{
keyValues[Uri.EscapeDataString(Uri.UnescapeDataString(key))] = Uri.EscapeDataString(Uri.UnescapeDataString(value ?? ""));

return this;
}

public AppQueryStringCollection Add(AppQueryStringCollection queryStringCollection)
{
foreach (var kv in queryStringCollection.keyValues)
{
keyValues[kv.Key] = kv.Value;
}

return this;
}

public AppQueryStringCollection Remove(string key)
{
keyValues.Remove(Uri.EscapeDataString(Uri.UnescapeDataString(key)));

return this;
}

public AppQueryStringCollection Clear()
{
keyValues.Clear();
return this;
}

public bool IsEmpty => keyValues.Any() is false;

public string? this[string key]
{
get
{
key = Uri.EscapeDataString(Uri.UnescapeDataString(key));
if (keyValues.TryGetValue(key, out var value))
return value;
return null;
}
set => Add(key, value);
}

public override string ToString()
{
return string.Join("&", keyValues.Select(kv => $"{kv.Key}={kv.Value}"));
return string.Join("&", this.Select(kv => $"{Uri.EscapeDataString(Uri.UnescapeDataString(kv.Key))}={Uri.EscapeDataString(Uri.UnescapeDataString(kv.Value?.ToString() ?? ""))}"));
}

public static AppQueryStringCollection Parse(string query)
Expand Down
Loading