简体   繁体   English

C#ASP.NET QueryString解析器

[英]C# ASP.NET QueryString parser

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. 任何意见或建议,以使其更好。

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 您可以使用以下命令从URL中提取查询字符串

 new Uri(url).Query

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. 此外,我强烈建议您为intDateTime指定要使用的区域性-它实际上不应取决于服务器碰巧所处的区域性。(如果您有代码来猜测用户的区域性,则可以最后,我还建议您支持一组指定良好的DateTime格式,而不是默认使用的TryParse支持的格式。 (I pretty much always use ParseExact / TryParseExact instead of Parse / TryParse .) (我几乎总是使用ParseExact / TryParseExact而不是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). 请注意,考虑到该value已经是一个字符串,字符串版本实际上不需要执行任何操作(尽管您当前的代码会将“”转换为null ,这可能是您想要的,也可能不是您想要的)。

I've written the following method to parse the QueryString to strongly typed values: 我编写了以下方法来将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;
}

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. 对于?productId=5的查询字符串, bool值为true,而int productId等于5。

For a querystring of ?productId=hello the bool would be false and int productId would equal 0. 对于?productId=hello的查询字符串, bool将为false,而int productId将为0。

For a querystring of ?noProductId=notIncluded the bool would be false and int productId would equal 0. 对于?noProductId=notIncluded的查询字符串, bool将为false,而int productId将等于0。

This is an old answer, but i've done the following: 这是一个旧答案,但是我已经完成了以下工作:

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

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. 如果未提供参数,则返回所需的默认值,从defaultValue推断类型,并根据需要引发转换异常。

Usage is as follows:- 用法如下:

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

It seems to me that you are doing a lot of unecesary type convertions. 在我看来,您正在执行许多不必要的类型转换。 The tempValue variables arere leady of the type you are trying to return. tempValue变量导致您尝试返回的类型。 Likewise in the string case the value is already a string so just return it instead. 同样,在字符串的情况下,该值已经是字符串,因此只需返回它即可。

Based on Ronalds answer I have updated my own querystring parsing method. 基于Ronalds的答案,我更新了自己的querystring解析方法。 The way I use it is to add it as an extension method on the Page object so its easy for me to check querystring values and types and redirect if the page request is not valid. 我使用它的方式是将其添加为Page对象上的扩展方法,因此对我来说很容易检查querystring值和类型,并在页面请求无效时重定向。

The extension method looks like this: 扩展方法如下所示:

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

This lets me do things like the following: 这使我可以执行以下操作:

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

I can then write the rest of my code and rely on the existence and correct format of the querystring item so I dont have to test it each time I want to access it. 然后,我可以编写其余代码,并依靠querystring项目的存在和正确格式,因此我不必在每次访问它时都进行测试。

Note: If you are using pre .net 4 then you will also want the following RedirectPermanent extension method: 注意:如果使用的是.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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM