C# ASP.NET QueryString 解析器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/574868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 08:51:04  来源:igfitidea点击:

C# ASP.NET QueryString parser

c#asp.netquery-string

提问by Andre Gallo

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.

任何意见或建议,以使其更好,不胜感激。

回答by Jon Skeet

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 intand DateTimeyou 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 DateTimeformats rather than just whatever TryParsesupports by default. (I pretty much alwaysuse ParseExact/TryParseExactinstead of Parse/TryParse.)

此外,我强烈建议,对于intDateTime指定的文化来使用-它真的不应该依赖于服务器恰好是在文化(如果你有代码来猜测用户的文化,你可以使用它。取而代之。)最后,我还建议支持一组明确指定的DateTime格式,而不仅仅是TryParse默认情况下支持的任何格式。(我几乎总是使用ParseExact/TryParseExact而不是Parse/ TryParse。)

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

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

回答by JohannesH

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. Likewise in the string case the value is already a string so just return it instead.

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

回答by Adam Ralph

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

回答by Simon_Weaver

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

回答by Ronald

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=5the boolwould be true and int productIdwould equal 5.

对于一个查询字符串?productId=5bool情况是真实的和int productId将等于5。

For a querystring of ?productId=hellothe boolwould be false and int productIdwould equal 0.

对于一个查询字符串?productId=hellobool会是假的和int productId将等于0。

For a querystring of ?noProductId=notIncludedthe boolwould be false and int productIdwould equal 0.

对于一个查询字符串?noProductId=notIncludedbool会是假的和int productId将等于0。

回答by rtpHarry

Based on Ronalds answerI have updated my own querystring parsing method. 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.

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

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.

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

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

回答by Byron Whitlock

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

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

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