Mega Code Archive

 
Categories / C# / Network
 

Parse the query string in the URI into a KeyValuePair

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SocialKit.LightRest {     /// <summary>     /// Provides helper methods for common tasks.     /// </summary>     public static class RestUtility     {         static string unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";         /// <summary>         /// Represents the System.Text.Encoding.Default.         /// </summary>         public static readonly Encoding DefaultEncoding = Encoding.Default;         /// <summary>         /// Encodes a URL string with UTF8 encoding.         /// </summary>         /// <param name="source">The text to encode.</param>         /// <returns></returns>         public static string UrlEncode(string source)         {             return UrlEncode(source, Encoding.UTF8);         }         /// <summary>         /// Encodes a URL string with the specified encoding.         /// </summary>         /// <param name="source">The text to encode.</param>         /// <param name="encoding">The System.Text.Encoding object that specifies the encoding scheme.</param>         /// <returns></returns>         public static string UrlEncode(string source, Encoding encoding)         {             if (source == null)                 return null;             if (string.IsNullOrEmpty(source))                 return string.Empty;             if (encoding == null)                 encoding = DefaultEncoding;             var buffer = new StringBuilder();             foreach (var b in encoding.GetBytes(source))             {                 if (b < 128 && unreservedChars.IndexOf((char)b) != -1)                 {                     buffer.Append((char)b);                 }                 else                 {                     buffer.AppendFormat("%{0:X2}", b);                 }             }             return buffer.ToString();         }         /// <summary>         /// Converts a string that has been encoded for transmission in a URL into a decoded string.          /// </summary>         /// <param name="source">The URL-encoded string to decode.</param>         /// <returns></returns>         public static string UrlDecode(string source)         {             return UrlDecode(source, Encoding.UTF8);         }         /// <summary>         /// Converts a URL-encoded string into a decoded string, using the specified encoding object.          /// </summary>         /// <param name="source">The URL-encoded string to decode.</param>         /// <param name="encoding">The System.Text.Encoding object that specifies the encoding scheme.</param>         /// <returns></returns>         public static string UrlDecode(string source, Encoding encoding)         {             if (source == null)                 return null;             if (string.IsNullOrEmpty(source))                 return string.Empty;             if (encoding == null)                 encoding = DefaultEncoding;             var bytes = new List<byte>();             for (int i = 0; i < source.Length; i++)             {                 var c = source[i];                 if (unreservedChars.IndexOf(c) != -1)                 {                     bytes.Add((byte)c);                 }                 else if (c == '%' && i < source.Length - 2)                 {                     var n1 = HexToInt(source[i + 1]);                     var n2 = HexToInt(source[i + 2]);                     if (n1 >= 0 && n2 >= 0)                     {                         var b = (byte)((n1 << 4) | n2);                         i += 2;                         bytes.Add(b);                     }                 }             }             return encoding.GetString(bytes.ToArray(), 0, bytes.Count);         }         /// <summary>         /// Converts an hex char to an integer.         /// </summary>         /// <param name="c"></param>         /// <returns></returns>         static int HexToInt(char c)         {             if ((c >= '0') && (c <= '9'))             {                 return (c - '0');             }             if ((c >= 'a') && (c <= 'f'))             {                 return ((c - 'a') + 10);             }             if ((c >= 'A') && (c <= 'F'))             {                 return ((c - 'A') + 10);             }             return -1;         }         /// <summary>         /// Parse the query string in the URI into a KeyValuePair&lt;string, string&gt; collection.         /// The keys and values will be URL decoded.         /// </summary>         /// <param name="query">The query string to parse.</param>         /// <returns>A keys and values collection.</returns>         public static IEnumerable<KeyValuePair<string, string>> ParseQueryString(string query)         {             if (query == null)                 throw new ArgumentNullException("query");             if (query.StartsWith("?"))                 query = query.Substring(1);             if (string.IsNullOrEmpty(query))                 return new KeyValuePair<string, string>[] { };             var values = new List<KeyValuePair<string, string>>();             int length = query.Length;             int startIndex, equalIndex;             for (int i = 0; i < length; i++)             {                 startIndex = i;                 equalIndex = -1;                 while (i < length)                 {                     char c = query[i];                     if (c == '=')                     {                         if (equalIndex < 0)                         {                             equalIndex = i;                         }                     }                     else if (c == '&')                     {                         break;                     }                     i++;                 }                 string key = null;                 string value = null;                 if (equalIndex >= 0)                 {                     key = query.Substring(startIndex, equalIndex - startIndex);                     value = query.Substring(equalIndex + 1, (i - equalIndex) - 1);                 }                 else                 {                     //standalone value is key or value?                     key = query.Substring(startIndex, i - startIndex);                 }                 if (value == null)                 {                     value = string.Empty;                 }                 values.Add(new KeyValuePair<string, string>(UrlDecode(key), UrlDecode(value)));             }             return values;         }         /// <summary>         /// Gets a string indicates the URI without query string.         /// </summary>         /// <param name="uri">The URI to normalize.</param>         /// <returns>The host and path of the URI.</returns>         public static string NormalizeUriWithoutQuery(Uri uri)         {             if (!uri.IsAbsoluteUri)                 throw new ArgumentOutOfRangeException("uri", "The relative URI is not supported.");             var normalizedUri = string.Format("{0}://{1}", uri.Scheme, uri.Host);             if (!((uri.Scheme == "http" && uri.Port == 80) || (uri.Scheme == "https" && uri.Port == 443)))             {                 normalizedUri += ":" + uri.Port;             }             normalizedUri += uri.AbsolutePath;             return normalizedUri;         }         /// <summary>         /// Extract encoding from the contentType string, or returns the fallback value.         /// </summary>         /// <param name="contentType">The contentType string.</param>         /// <param name="fallback">If no encoding found, returns this value.</param>         /// <returns>A System.Text.Encoding value.</returns>         public static Encoding ExtractEncoding(string contentType, Encoding fallback)         {             if (string.IsNullOrEmpty(contentType))             {                 return fallback;             }             //find charset             var values = contentType.Split(';');             var charsetPair = values.FirstOrDefault(v => v.Trim().StartsWith("charset", StringComparison.InvariantCultureIgnoreCase));             if (charsetPair == null)                 return fallback;             var charset = charsetPair.Split('=')[1];             return Encoding.GetEncoding(charset);         }         /// <summary>         /// Extract encoding from the contentType string.         /// </summary>         /// <param name="contentType">The contentType string.</param>         /// <returns>A System.Text.Encoding value.</returns>         public static Encoding ExtractEncoding(string contentType)         {             return ExtractEncoding(contentType, Encoding.Default);         }     } }