public bool TryGetParam <T>(string key, out T value)
        {
            // try to find a parameter with matching name across the cookies, query parameters, request headers and extended properties
            if (QueryParams.TryGetValue(key, out var queryParamValue))
            {
                value = (T)queryParamValue;
                return(true);
            }

            if (RequestHeaders.TryGetValue(key, out var headerValue))
            {
                value = (T)headerValue;
                return(true);
            }

            if (Cookies.TryGetValue(key, out var cookieValue))
            {
                value = (T)cookieValue;
                return(true);
            }

            if (ExtendedProperties.TryGetValue(key, out var extendedValue))
            {
                value = (T)extendedValue;
                return(true);
            }

            // the parameter doesn't exist so return null/false
            value = default(T);
            return(false);
        }
        private T GetValue <T>(string key)
        {
            object value;

            if (Method == "GET" || Method == "DELETE")
            {
                QueryParams = QueryParams ?? new Dictionary <string, object>();

                if (QueryParams.TryGetValue(key, out value))
                {
                    return((T)value);
                }

                return(default(T));
            }

            FormParams = FormParams ?? new Dictionary <string, object>();

            if (FormParams.TryGetValue(key, out value))
            {
                return((T)value);
            }

            return(default(T));
        }