簡體   English   中英

C#ASP.NET QueryString解析器

[英]C# ASP.NET QueryString parser

如果您一直在尋找一種解析查詢字符串值的好方法,那么我想出了這個方法:

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

我一直想擁有這樣的東西,最終做到正確……至少我是這么認為的……

該代碼應該是自我解釋的...

任何意見或建議,以使其更好。

解析(如果您不想進行類型轉換)的一種簡單方法是

 HttpUtility.ParseQueryString(queryString);

您可以使用以下命令從URL中提取查詢字符串

 new Uri(url).Query

鑒於您只能處理三種不同的類型,我建議使用三種不同的方法-泛型方法最好與類型約束所允許的每個類型參數一起使用,這是最好的。

此外,我強烈建議您為intDateTime指定要使用的區域性-它實際上不應取決於服務器碰巧所處的區域性。(如果您有代碼來猜測用戶的區域性,則可以最后,我還建議您支持一組指定良好的DateTime格式,而不是默認使用的TryParse支持的格式。 (我幾乎總是使用ParseExact / TryParseExact而不是Parse / TryParse 。)

請注意,考慮到該value已經是一個字符串,字符串版本實際上不需要執行任何操作(盡管您當前的代碼會將“”轉換為null ,這可能是您想要的,也可能不是您想要的)。

我編寫了以下方法來將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值為true,而int productId等於5。

對於?productId=hello的查詢字符串, bool將為false,而int productId將為0。

對於?noProductId=notIncluded的查詢字符串, bool將為false,而int productId將等於0。

這是一個舊答案,但是我已經完成了以下工作:

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

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

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

在我看來,您正在執行許多不必要的類型轉換。 tempValue變量導致您嘗試返回的類型。 同樣,在字符串的情況下,該值已經是字符串,因此只需返回它即可。

基於Ronalds的答案,我更新了自己的querystring解析方法。 我使用它的方式是將其添加為Page對象上的擴展方法,因此對我來說很容易檢查querystring值和類型,並在頁面請求無效時重定向。

擴展方法如下所示:

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

然后,我可以編寫其余代碼,並依靠querystring項目的存在和正確格式,因此我不必在每次訪問它時都進行測試。

注意:如果使用的是.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