Build and parse URL query strings with escaping

C#
using System;
using System.Collections.Generic;
using System.Linq;

static string BuildQuery(IReadOnlyDictionary<string, string> pairs) =>
    string.Join("&", pairs.Select(p =>
        $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}"));

static Dictionary<string, string> ParseQuery(string query)
{
    var result = new Dictionary<string, string>(StringComparer.Ordinal);
    foreach (var pair in query.TrimStart('?').Split('&', StringSplitOptions.RemoveEmptyEntries))
    {
        string[] parts = pair.Split('=', 2);
        string key = Uri.UnescapeDataString(parts[0].Replace('+', ' '));
        result[key] = parts.Length == 2 ? Uri.UnescapeDataString(parts[1].Replace('+', ' ')) : "";
    }
    return result;
}