C#ASP.NET QueryString解析器

时间:2009-02-22 12:45:31

标签: c# asp.net query-string

如果您一直在寻找一种简洁明了的方法来解析查询字符串值,我想出了这个:

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

我一直想拥有这样的东西,最后做对了......至少我是这么认为的......

代码应该是自我解释的......

任何评论或建议都会让人感觉更好。

7 个答案:

答案 0 :(得分:34)

一种简单的解析方法(如果你不想进行类型转换)是

 HttpUtility.ParseQueryString(queryString);

您可以使用

从URL中提取查询字符串
 new Uri(url).Query

答案 1 :(得分:5)

鉴于你只处理三种不同的类型,我建议使用三种不同的方法 - 当它们适用于类型约束允许的每个类型参数时,泛型方法最好。

此外,我强烈建议您为intDateTime指定要使用的文化 - 它不应该真正依赖于服务器所处的文化。(如果您有用来猜测用户文化的代码,你可以改用它。)最后,我还建议支持一组明确指定的DateTime格式,而不仅仅是TryParse默认支持的格式。 (我几乎总是使用ParseExact / TryParseExact而不是Parse / TryParse。)

请注意,字符串版本并不需要做任何事情,因为value已经是一个字符串(尽管您当前的代码将“”转换为null,这可能是也可能不是你想要的。)

答案 2 :(得分:3)

我编写了以下方法来将QueryString解析为强类型值:

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

用法示例:

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

对于?productId=5的查询字符串,bool为真,int productId等于5。

对于?productId=hello的查询字符串,bool将为false,int productId将为0。

对于?noProductId=notIncluded的查询字符串,bool将为false,int productId将为0。

答案 3 :(得分:2)

在我的应用程序中,我一直在使用以下功能: -

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

如果未提供参数,则返回所需的默认值,从defaultValue推断类型,并根据需要引发转换异常。

用法如下: -

var foo = WebUtil.GetValue("foo", ViewState, default(int?));

答案 4 :(得分:2)

这是一个陈旧的答案,但我已经完成了以下工作:

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

答案 5 :(得分:1)

在我看来,你正在做很多无助的类型转换。 tempValue变量是您尝试返回的类型的主要变量。同样在字符串的情况下,值已经是一个字符串,所以只需返回它。

答案 6 :(得分:0)

基于Ronalds answer我更新了自己的查询字符串解析方法。我使用它的方法是将它作为扩展方法添加到Page对象上,这样我就可以轻松检查查询字符串值和类型,并在页面请求无效时重定向。

扩展方法如下所示:

public static class PageHelpers
{
    public static void RequireOrPermanentRedirect<T>(this System.Web.UI.Page page, string QueryStringKey, string RedirectUrl)
    {
        string QueryStringValue = page.Request.QueryString[QueryStringKey];

        if(String.IsNullOrEmpty(QueryStringValue))
        {
            page.Response.RedirectPermanent(RedirectUrl);
        }

        try
        {
            T value = (T)Convert.ChangeType(QueryStringValue, typeof(T));
        }
        catch
        {
            page.Response.RedirectPermanent(RedirectUrl);
        }
    }
}

这让我可以做以下事情:

protected void Page_Load(object sender, EventArgs e)
{
    Page.RequireOrPermanentRedirect<int>("CategoryId", "/");
}

然后我可以编写其余的代码并依赖查询字符串项的存在和正确的格式,所以每次我想访问它时都不必测试它。

注意:如果您使用的是.net 4,那么您还需要以下RedirectPermanent扩展方法:

public static class HttpResponseHelpers
{
    public static void RedirectPermanent(this System.Web.HttpResponse response, string uri)
    {
        response.StatusCode = 301;
        response.StatusDescription = "Moved Permanently";
        response.AddHeader("Location", uri);
        response.End();
    }
}