MaxBeauchemin
2/4/2020 - 4:48 PM

HTTP Encode URI Parameters

//Sample Call
var url = BuildURL(endpoint, parameters);

/// <summary>
/// Takes the provided endpoint and adds the encoded version of the parameters to the URL string
/// </summary>
/// <param name="endpoint"></param>
/// <param name="parameters"></param>
/// <returns></returns>
public static string BuildURL(string endpoint, Dictionary<string, string> parameters)
{
  var parameterStringBuilder = new StringBuilder();
  if (parameters != null)
  {
    foreach (var param in parameters)
    {
      parameterStringBuilder.Append(String.Format("{0}={1}&", param.Key, EncodeURIComponent(param.Value)));
    }
  }
  var paramString = parameterStringBuilder.ToString().TrimEnd('&');

  var url = string.Format("{0}?{1}", endpoint, paramString).TrimEnd('?');

  return url;
}

/// <summary>
/// Encodes the input string to a valid parameter to be used in an HTTP URI
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string EncodeURIComponent(string input)
{
  if (input == null) return string.Empty;

  var chars = input.ToCharArray();

  var sb = new StringBuilder();
  foreach (var c in chars)
  {
    if (Char.IsLetterOrDigit(c))
    {
      sb.Append(c);
    }
    else
    {
      sb.Append(Uri.HexEscape(c));
    }
  }

  return sb.ToString();
}

//Testing

var codes = new Dictionary<string, string>
{
    { " ", "%20" },
    { "!", "%21" },
    { "\"", "%22" },
    { "#", "%23" },
    { "$", "%24" },
    { "%", "%25" },
    { "&", "%26" },
    { "'", "%27" },
    { "(", "%28" },
    { ")", "%29" },
    { "*", "%2A" },
    { "+", "%2B" },
    { ",", "%2C" },
    { "-", "%2D" },
    { ".", "%2E" },
    { "/", "%2F" },
    { ":", "%3A" },
    { ";", "%3B" },
    { "<", "%3C" },
    { "=", "%3D" },
    { ">", "%3E" },
    { "?", "%3F" },
    { "@", "%40" },
    { "{", "%7B" },
    { "}", "%7D" },
    { "[", "%5B" },
    { "]", "%5D" },
    { "`", "%60" },
    { "~", "%7E" },
    { "^", "%5E" },
    { "|", "%7C" },
    { "Hello there", "Hello%20there" },
    { "What/is going&on", "What%2Fis%20going%26on" },
    { "POLY&KDF#12{impossible}", "POLY%26KDF%2312%7Bimpossible%7D" }
};

foreach (var code in codes)
{
    Assert.AreEqual(code.Value, HTTPRest.EncodeURIComponent(code.Key), string.Format("Expected '{0}' to encode to '{1}'", code.Key, code.Value));
}