-3

I want to pass C# object as query string & i used following code to get the desired result.

 class Program
    {
        public static 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());
        }
        static void Main(string[] args)
        {
            Filters fil = new Filters();
            fil.Age = 10;
            fil.Id = "some id";

            fil.Divisions = new List<string>();
            fil.Divisions.Add("div 1");
            fil.Divisions.Add("div 2");
            fil.Divisions.Add("div 3");

            fil.Names = new List<string>();
            fil.Names.Add("name 1");
            fil.Names.Add("name 2");
            fil.Names.Add("name 3");

            var queryStr = GetQueryString(fil);
            Console.ReadKey();
        }



    }

    public class Filters
    {
        public List<string> Names { get; set; }
        public List<string> Divisions { get; set; }
        public int Age { get; set; }
        public string Id { get; set; }
    }

using the above code give me following result:

Names=System.Collections.Generic.List%601%5bSystem.String%5d&Divisions=System.Collections.Generic.List%601%5bSystem.String%5d&Age=10&Id=some+id

The output is not a valid query string. I need help to convert any POCO class into query string format.

I have a similar JavaScript object and i am able to convert it into correct query string.

{
  "id":"some id",
  "age":10,
  "division":["div 1","div 2","div 3"],
  "names":["name 1","name 2","name 3"]
}

using Jquery I can say $.param(obj) and this will result in:

"id=some+id&age=10&division%5B%5D=div+1&division%5B%5D=div+2&division%5B%5D=div+3&names%5B%5D=name+1&names%5B%5D=name+2&names%5B%5D=name+3"

I want a similar output using c#.

SharpCoder
  • 18,279
  • 43
  • 153
  • 249
  • 1
    1) Why is that long query string? why not an ID? 2) and if you have - why not serialize it to a JSON instead ? – Royi Namir Aug 16 '16 at 18:36
  • OK, write code to do that. What are you having trouble with? – 15ee8f99-57ff-4f92-890c-b56153 Aug 16 '16 at 18:38
  • @RoyiNamir: I need to pas this information to a webpage as query string. I am trying to call a page & that page expects values to be passed as query string – SharpCoder Aug 16 '16 at 18:38
  • @EdPlunkett: I added some code but its not producing the desired result – SharpCoder Aug 16 '16 at 18:39
  • further to Royi - there's a limit to the length of a query string as well. You may want to consider passing it in a POST as part of the payload, and not in a GET query string. Anway, your result *does* look like a valid query string. I think what you mean is that you want the values of the object, but you're outputting the type instead – Jonathan Aug 16 '16 at 18:40
  • basically you need to transfer infomration between webpages. This can be done via : * Session * RedirectToAction * Query string ( usually an ID) – Royi Namir Aug 16 '16 at 18:42
  • @Jonathan: I have added the out produced by `jquery's $.param()`. I want to generate similar output. – SharpCoder Aug 16 '16 at 18:42
  • No, I said "write code". Look at the string you're trying to imitate. Figure out what the format is. Then write code to produce that format. Don't just pick one function at random and give up when it doesn't magically produce the result you were hoping for. You have the desired result right in front of you. It's not that hard. – 15ee8f99-57ff-4f92-890c-b56153 Aug 16 '16 at 18:44
  • @RoyiNamir: I am not using ASP.NET. I am using ASP.NET web api which will receive a object as input. I need to convert that object into query string. Then I will call an command using `Process` class. this command expects a url with query string as argument. So I am calling a URL using process class and not directly. I need to pass this object to another page(which is called through process class) – SharpCoder Aug 16 '16 at 18:48
  • Hi SharpCoder. Most of the output *does* look similar or the same, but the names parameter is incorrect. You are.ToString()-ing the object, which will give you the name of the type. You want to .ToString() the values. Either hard code it (perhaps with String.Join(), or create a recursive method that takes IEnumerable and outputs – Jonathan Aug 16 '16 at 18:48
  • This answer will work for easily nested objects as well https://stackoverflow.com/a/60936159/9590885 – giorgi02 May 30 '21 at 11:09

1 Answers1

1

It looks like The problem is that you are calling ToString() on your objects. List<String>.ToString() will return "List<System.String>", which is what you're seeing, except URL encoded.

You will need to either:

  1. Provide an iterface with a ToQueryString method:

    public interface IQueryStringable
    {
        string ToQueryString();
    }
    

    and have all classes you might want to use as query strings implement it, or

  2. Rewrite your reflection so that it iterates sequences. Something like (pseudocode):

    1. Get property.
    2. See if it is an instance of IEnumerable. If not, proceed as before
    3. Otherwise:
    4. for each item, construct a string consisting of the property name, "[]=" and the value of that item.
    5. Concatenate the produced strings and urlencode it.

For sanity's sake, I would recommend option 1, and I enjoy playing with reflection. It gets more complex if you want to allow arbitrary nesting of classes.

RoadieRich
  • 6,330
  • 3
  • 35
  • 52