1

I need to serialise an object model containing arrays into a query string, I have the following code:

       public static string ToQueryString(this object query)
    {
        var result = new List<string>();
        var properties = query.GetType().GetProperties().Where(p => p.GetValue(query, null) != null && p.GetValue(query, null).ToString() != "0");

        foreach (var p in properties)
        {
            var value = p.GetValue(query, null);
            var collection = value as ICollection;
            if (collection != null)
            {
                result.AddRange(from object o in collection select string.Format("{0}={1}", p.Name, HttpUtility.UrlEncode(o.ToString())));
            }
            else
            {
                result.Add($"{p.Name}={HttpUtility.UrlEncode(value.ToString())}");
            }
        }

        return string.Join("&", result.ToArray());
    }

and the following example model:

        var model = new exampleModel()
        {
            OrderBy = "name",
            OrderByDesc = true,
            PersonName= "John",
            Languages = new string[] { "French", "English", "Spanish" }
        };

When the model is serialized the querystring is converted like this:

"OrderBy=name&OrderByDesc=true&PersonName=John&Languages=French&Languages=English&Languages=Spanish"

As you can see this is not desirable as the property "Languages" is repeated in the query string for each value in the collection. Does anyone know how can I manage to get the query string such as:

"OrderBy=name&OrderByDesc=true&PersonName=John&Languages=French,English,Spanish"

1
  • Note: if you would like to minimize the need for scrolling horizontally, you could reduce indentation by selecting the relevant portion of code, and clicking [{ }] button at the top of the editor. Commented Dec 13, 2017 at 18:08

2 Answers 2

2

Change your handling of ICollection to format as you would like:

  public static string ToQueryString(this object query)
{
    var result = new List<string>();
    var properties = query.GetType().GetProperties().Where(p => p.GetValue(query, null) != null && p.GetValue(query, null).ToString() != "0");

    foreach (var p in properties)
    {
        var value = p.GetValue(query, null);
        var collection = value as ICollection;
        if (collection != null)
        {
            result.Add(p.Name+"="+string.Join(",", collection.Select(o => HttpUtility.UrlEncode(o.ToString())).ToArray());
        }
        else
        {
            result.Add($"{p.Name}={HttpUtility.UrlEncode(value.ToString())}");
        }
    }

    return string.Join("&", result.ToArray());
}
Sign up to request clarification or add additional context in comments.

Comments

1

Check if the property value is an array and since arrays implement IEnumerable you can create a generic function like so:

public string ConvertToQueryString(object obj)
{
    var properties = from p in obj.GetType().GetProperties()
                 where p.GetValue(obj, null) != null
                 select p.Name + "=" + (
                     p.GetValue(obj, null).GetType().IsArray ?
                     string.Join(",", ((IEnumerable)p.GetValue(obj, null)).Cast<object>().Select(x => x.ToString()).ToArray()) :
                     p.GetValue(obj, null).ToString() 
                     );

    return string.Join("&", properties.ToArray());
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.