restsharp / RestSharp

Simple REST and HTTP API Client for .NET
https://restsharp.dev
Apache License 2.0
9.6k stars 2.34k forks source link

ParseUrlQueryString #48

Closed prabirshrestha closed 13 years ago

prabirshrestha commented 14 years ago

I think its a good idea to expose ParseUrlQueryString also, especailly when dealing with OAuth2.

they return results in. https:\/\/graph.facebook.com\/1237476932\/feed?limit=25&oauth_token=1314033135-100001241534829%7C1237417Cq_Jgbyd1L87YiLi-ZAfyFo.&until=2010-07-12T09%3A53%3A41%2B0000

so extracting appropriate querystring would be helpful if restsharp already contains this method. desktop supports public static NameValueCollection ParseQueryString(string query) from HttpUtility class but silverlight doesn't. it then becomes problem of writing custom method for silverlight. another problem with silverlight is that it doesn't support the class NameValueCollection. after checking the QueryString in silverlight it seems to rather return IDictionary<string,string> which i think is pretty reasonable. so mite be Restsharp can have a function called

public static IDictionary<string,string> ParseQueryString(string query)

so that it works in both desktop and silverlight using the same api.

or if it wants to mimic the feature of NameValueCollection IDictionary<string,string[]> or IDictionary<string,List> might be appropriate.

anyways heres the code, did a slight change from the mono HttpUtility code.

public static IDictionary<string, List> ParseQueryString(string query) { var result = new Dictionary<string, List>();

        if (string.IsNullOrEmpty(query))
            return result;

        string decoded = HtmlDecode(query);
        int decodedLength = decoded.Length;
        int namePos = 0;
        bool first = true;

        while (namePos <= decodedLength)
        {
            int valuePos = -1, valueEnd = -1;
            for (int q = namePos; q < decodedLength; q++)
            {
                if (valuePos == -1 && decoded[q] == '=')
                {
                    valuePos = q + 1;
                }
                else if (decoded[q] == '&')
                {
                    valueEnd = q;
                    break;
                }
            }

            if (first)
            {
                first = false;
                if (decoded[namePos] == '?')
                    namePos++;
            }

            string name, value;
            if (valuePos == -1)
            {
                name = null;
                valuePos = namePos;
            }
            else
            {
                name = UrlDecode(decoded.Substring(namePos, valuePos - namePos - 1));
            }
            if (valueEnd < 0)
            {
                namePos = -1;
                valueEnd = decoded.Length;
            }
            else
            {
                namePos = valueEnd + 1;
            }
            value = UrlDecode(decoded.Substring(valuePos, valueEnd - valuePos));

            if (name != null)
            {
                if (result.ContainsKey(name))
                    result["name"].Add(value);
                else
                    result.Add(name, new List<string> { value });
            }

            if (namePos == -1)
                break;
        }

        return result;
    }
johnsheehan commented 13 years ago

willing to review a pull request on this if you want to implement it.

prabirshrestha commented 13 years ago

i could write the code for it, but what should be the return type for

public static IDictionary<string, List<string>> ParseQueryString(string query)

IDictionary<string, List<string>> or Dictionary<string,List<string>> or NameValueCollection (i don't prefer this one coz, namevaluecollection doesnt work in silverlight and windows phone) or just IDictionary<string,string> (this one has a defect, in the sense, ?id=123&name=asd&id=234 if the querystring (id) appears twice then it wont work. wierd case though)

johnsheehan commented 13 years ago

can you start a discussion the google group? thanks!

prabirshrestha commented 13 years ago

discussion created at google groups: http://groups.google.com/group/restsharp/browse_thread/thread/418b236edef573d2#

please use google groups for further discussion.