.NET equivalent to JQuery.param ()

I would like to improve my web API tests and look for a way to improve the URL format.

var filter = new {
    State = new[] {"A", "C"},
    MaxAge = 60,
    POI = new { Lat = 40, Long = -130 }
};

      

What can I call to format the query string exactly like the JQuery.param () function ?

+3


source to share


2 answers


There you can find an extension method to help you convert an object to a query string

public static class UrlHelpers
{
    public static string ToQueryString(this object request, string separator = ",")
    {
        if (request == null)
            throw new ArgumentNullException("request");

        // Get all properties on the object
        var properties = request.GetType().GetProperties()
            .Where(x => x.CanRead)
            .Where(x => x.GetValue(request, null) != null)
            .ToDictionary(x => x.Name, x => x.GetValue(request, null));

        // Get names for all IEnumerable properties (excl. string)
        var propertyNames = properties
            .Where(x => !(x.Value is string) && x.Value is IEnumerable)
            .Select(x => x.Key)
            .ToList();

        // Concat all IEnumerable properties into a comma separated string
        foreach (var key in propertyNames)
        {
            var valueType = properties[key].GetType();
            var valueElemType = valueType.IsGenericType
                                    ? valueType.GetGenericArguments()[0]
                                    : valueType.GetElementType();
            if (valueElemType.IsPrimitive || valueElemType == typeof (string))
            {
                var enumerable = properties[key] as IEnumerable;
                properties[key] = string.Join(separator, enumerable.Cast<object>());
            }
        }

        // Concat all key/value pairs into a string separated by ampersand
        return string.Join("&", properties
            .Select(x => string.Concat(
                Uri.EscapeDataString(x.Key), "=",
                Uri.EscapeDataString(x.Value.ToString()))));
    }
}

      



and use it like string querystring = example.ToQueryString();

+3


source


This is my extension method. It supports nesting. Javascript object is represented as a dictionary <string, object> and javascript array as IEnumerable.



public static class ToQueryStringExtension
{
    public static string ToQueryString(this Dictionary<string, object> obj)
    {
        if (obj == null) return "";

        string query = "";
        bool first = true;
        Dictionary<string, List<string>> data = ToQueryStringHelper(obj);
        foreach (KeyValuePair<string, List<string>> kvp in data)
        {
            string keyUrlencoded = UpperCaseUrlEncode(kvp.Key);
            foreach (string ele in kvp.Value)
            {
                if (first) first = false;
                else query += "&";
                query += keyUrlencoded + ele;
            }
        }

        return query;
    }

    private static Dictionary<string, List<string>> ToQueryStringHelper(Dictionary<string, object> obj)
    {
        Dictionary<string, List<string>> data = new Dictionary<string, List<string>>();
        foreach (KeyValuePair<string, object> kvp in obj)
        {
            if (kvp.Value is Dictionary<string, object>)
            {
                Dictionary<string, List<string>> dataInner = ToQueryStringHelper((Dictionary<string, object>)kvp.Value);
                if (dataInner.Count < 1) continue;
                data.Add(kvp.Key, new List<string>());
                foreach (KeyValuePair<string, List<string>> kvpInner in dataInner)
                {
                    string keyUrlencoded = UpperCaseUrlEncode("[" + kvpInner.Key + "]");
                    foreach (string ele in kvpInner.Value)
                    {
                        data[kvp.Key].Add(keyUrlencoded + ele);
                    }
                }
            }
            else if ((kvp.Value is IEnumerable) && !(kvp.Value is string))
            {
                Dictionary<string, object> objInner = new Dictionary<string, object>();
                IEnumerable list = (IEnumerable)kvp.Value;
                int inx = 0;
                foreach (object ele in list)
                {
                    objInner.Add(inx.ToString(), ele);
                    inx++;
                }

                Dictionary<string, List<string>> dataInner = ToQueryStringHelper(objInner);
                if (dataInner.Count < 1) continue;
                data.Add(kvp.Key, new List<string>());
                foreach (KeyValuePair<string, List<string>> kvpInner in dataInner)
                {
                    // index key can be removed in peripheral nodes
                    string keyUrlencoded = null;
                    if (kvpInner.Value.Count == 1 && kvpInner.Value[0].StartsWith("=")) keyUrlencoded = General.UpperCaseUrlEncode("[]");
                    else keyUrlencoded = UpperCaseUrlEncode("[" + kvpInner.Key + "]");
                    foreach (string ele in kvpInner.Value)
                    {
                        data[kvp.Key].Add(keyUrlencoded + ele);
                    }
                }
            }
            else
            {
                // Optional check if peripheral value type is known.
                //Type type = kvp.Value.GetType();
                //if (!(kvp.Value is Decimal) && !(kvp.Value is string) && !(type.IsPrimitive)) throw new Exception("Unknown peripheral type.");
                if (kvp.Value != null)
                {
                    data.Add(kvp.Key, new List<string>());
                    data[kvp.Key].Add("=" + UpperCaseUrlEncode(kvp.Value.ToString()));
                }
            }
        }
        return data;
    }

    public static string UpperCaseUrlEncode(string s)
    {
        char[] temp = HttpUtility.UrlEncode(s).ToCharArray();
        for (int i = 0; i < temp.Length - 2; i++)
        {
            if (temp[i] == '%')
            {
                temp[i + 1] = char.ToUpper(temp[i + 1]);
                temp[i + 2] = char.ToUpper(temp[i + 2]);
            }
        }
        return new string(temp);
    }
}

      

+1


source







All Articles