How do I serialize an object into query-string format? How do I serialize an object into query-string format? asp.net asp.net

How do I serialize an object into query-string format?


I'm 99% sure there's no built-in utility method for this. It's not a very common task, since a web server doesn't typically respond with a URLEncoded key/value string.

How do you feel about mixing reflection and LINQ? This works:

var foo = new EditListItemActionModel() {  Id = 1,  State = 26,  Prefix = "f",  Index = "oo",  ParentID = null};var properties = from p in foo.GetType().GetProperties()                 where p.GetValue(foo, null) != null                 select p.Name + "=" + HttpUtility.UrlEncode(p.GetValue(foo, null).ToString());// queryString will be set to "Id=1&State=26&Prefix=f&Index=oo"                  string queryString = String.Join("&", properties.ToArray());

Update:

To write a method that returns the QueryString representation of any 1-deep object, you could do this:

public string GetQueryString(object obj) {  var properties = from p in obj.GetType().GetProperties()                   where p.GetValue(obj, null) != null                   select p.Name + "=" + HttpUtility.UrlEncode(p.GetValue(obj, null).ToString());  return String.Join("&", properties.ToArray());}// Usage:string queryString = GetQueryString(foo);

You could also make it an extension method without much additional work

public static class ExtensionMethods {  public static string GetQueryString(this object obj) {    var properties = from p in obj.GetType().GetProperties()                     where p.GetValue(obj, null) != null                     select p.Name + "=" + HttpUtility.UrlEncode(p.GetValue(obj, null).ToString());    return String.Join("&", properties.ToArray());  }}// Usage:string queryString = foo.GetQueryString();


Building on the good ideas from other comments, I have made a generic extension method .ToQueryString(), which can be used on any object.

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()))));    }}

It will also work for objects that have properties of the type Array and generic Lists if they only contain primitives or strings.

Try it out, comments are welcome: Serialize object into a query string with Reflection


Using Json.Net it would be much easier, by serializing and then deserializing to key value pairs.

Here is a code example:

using Newtonsoft.Json;using System.Web;string ObjToQueryString(object obj){     var step1 = JsonConvert.SerializeObject(obj);     var step2 = JsonConvert.DeserializeObject<IDictionary<string, string>>(step1);     var step3 = step2.Select(x => HttpUtility.UrlEncode(x.Key) + "=" + HttpUtility.UrlEncode(x.Value));     return string.Join("&", step3);}