C# ASP.NET QueryString parser

21,577

Solution 1

A simple way to parse (if you dont want to do type conversions) is

 HttpUtility.ParseQueryString(queryString);

You can extract querystring from a URL with

 new Uri(url).Query

Solution 2

Given that you only handle three different types, I would suggest three different methods instead - generic methods are best when they work well with every type argument which is permitted by the type constraints.

In addition, I would strongly recommend that for int and DateTime you specify the culture to use - it shouldn't really depend on the culture the server happens to be in. (If you have code to guess the culture of the user, you could use that instead.) Finally, I'd also suggest supporting a well-specified set of DateTime formats rather than just whatever TryParse supports by default. (I pretty much always use ParseExact/TryParseExact instead of Parse/TryParse.)

Note that the string version doesn't really need to do anything, given that value is already a string (although your current code converts "" to null, which may or may not be what you want).

Solution 3

I've written the following method to parse the QueryString to strongly typed values:

public static bool TryGetValue<T>(string key, out T value, IFormatProvider provider)
{
    string queryStringValue = HttpContext.Current.Request.QueryString[key];

    if (queryStringValue != null)
    {
        // Value is found, try to change the type
        try
        {
            value = (T)Convert.ChangeType(queryStringValue, typeof(T), provider);
            return true;
        }
        catch
        {
            // Type could not be changed
        }
    }

    // Value is not found, return default
    value = default(T);
    return false;
}

Usage example:

int productId = 0;
bool success = TryGetValue<int>("ProductId", out productId, CultureInfo.CurrentCulture);

For a querystring of ?productId=5 the bool would be true and int productId would equal 5.

For a querystring of ?productId=hello the bool would be false and int productId would equal 0.

For a querystring of ?noProductId=notIncluded the bool would be false and int productId would equal 0.

Solution 4

This is an old answer, but i've done the following:

            string queryString = relayState.Split("?").ElementAt(1);
            NameValueCollection nvc = HttpUtility.ParseQueryString(queryString);

Solution 5

In my application I've been using the following function:-

public static class WebUtil
{
    public static T GetValue<T>(string key, StateBag stateBag, T defaultValue)
    {
        object o = stateBag[key];

        return o == null ? defaultValue : (T)o;
    }
}

The required default is returned if the parameter has not been supplied, the type is inferred from defaultValue and casting exceptions are raised as necessary.

Usage is as follows:-

var foo = WebUtil.GetValue("foo", ViewState, default(int?));
Share:
21,577
dcdrns
Author by

dcdrns

Founder, CTO and Martial Artist.

Updated on September 05, 2020

Comments

  • dcdrns
    dcdrns over 3 years

    If you have been looking for a nice and clean way to parse your query string values, I have come up with this:

        /// <summary>
        /// Parses the query string and returns a valid value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">The query string key.</param>
        /// <param name="value">The value.</param>
        protected internal T ParseQueryStringValue<T>(string key, string value)
        {
            if (!string.IsNullOrEmpty(value))
            {
                //TODO: Map other common QueryString parameters type ...
                if (typeof(T) == typeof(string))
                {
                    return (T)Convert.ChangeType(value, typeof(T));
                }
                if (typeof(T) == typeof(int))
                {
                    int tempValue;
                    if (!int.TryParse(value, out tempValue))
                    {
                        throw new ApplicationException(string.Format("Invalid QueryString parameter {0}. The value " +
                                                                  "'{1}' is not a valid {2} type.", key, value, "int"));
                    }
                    return (T)Convert.ChangeType(tempValue, typeof(T));
                }
                if (typeof(T) == typeof(DateTime))
                {
                    DateTime tempValue;
                    if (!DateTime.TryParse(value, out tempValue))
                    {
                        throw new ApplicationException(string.Format("Invalid QueryString parameter {0}. The value " +
                                                             "'{1}' is not a valid {2} type.", key, value, "DateTime"));
                    }
                    return (T)Convert.ChangeType(tempValue, typeof(T));
                }
            }
            return default(T);
        }
    

    I have always wanted to have something like that and finally got it right ... at least I think so ...

    The code should be self explanatory ...

    Any comments or suggestions to make it better are appreciated.

  • Richard
    Richard about 15 years
    +1 for ParseExact/TryParseExact especially as you can pass an array of formats.
  • jrwren
    jrwren about 13 years
    This only works if url is a full url. If you have a relative url, then the Query member of Uri is not supported.