7

クエリ文字列の値を解析するための適切でクリーンな方法を探していた場合は、次の方法を思い付きました。

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

私はいつもそのようなものを持ちたいと思っていましたが、ついにそれがうまくいきました...少なくとも私はそう思います...

コードは自明である必要があります...

より良いものにするためのコメントや提案は大歓迎です。

4

7 に答える 7

34

解析する簡単な方法 (型変換をしたくない場合) は次のとおりです。

 HttpUtility.ParseQueryString(queryString);

URLからクエリ文字列を抽出するには

 new Uri(url).Query
于 2009-09-03T00:13:38.060 に答える
5

3 つの異なる型しか処理しない場合は、代わりに 3 つの異なるメソッドをお勧めします。型制約で許可されているすべての型引数でうまく機能する場合は、ジェネリック メソッドが最適です。

さらに、forintおよびDateTime使用するカルチャを指定することを強くお勧めします。サーバーがたまたま含まれているカルチャに実際に依存するべきではありません。(ユーザーのカルチャを推測するコードがある場合は、それを使用できます。最後に、デフォルトでサポートされているDateTimeものだけではなく、明確に指定された一連のフォーマットをサポートすることもお勧めTryParseします。(私はいつもParseExact/TryParseExactの代わりにParse/を使いますTryParse。)

すでに文字列であることを考えると、文字列バージョンは実際には何もする必要がないことに注意してvalueください (ただし、現在のコードは "" を に変換しますがnull、これは必要な場合とそうでない場合があります)。

于 2009-02-22T12:51:58.703 に答える
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 productId5 に等しくなります。

のクエリ文字列の?productId=hello場合boolは false になり、int productId0 になります。

のクエリ文字列の?noProductId=notIncluded場合boolは false になり、int productId0 になります。

于 2009-12-17T11:39:55.037 に答える
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?));
于 2009-02-22T13:02:04.823 に答える
2

これは古い答えですが、私は次のことを行いました:

            string queryString = relayState.Split("?").ElementAt(1);
            NameValueCollection nvc = HttpUtility.ParseQueryString(queryString);
于 2012-09-04T22:16:20.960 に答える
1

不必要な型変換をたくさんしているように思えます。tempValue 変数は、返そうとしている型のリードです。同様に、文字列の場合、値はすでに文字列であるため、代わりにそれを返します。

于 2009-02-22T12:54:08.603 に答える
0

Ronaldsの回答に基づいて、独自のクエリ文字列解析メソッドを更新しました。私が使用する方法は、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", "/");
}

その後、残りのコードを記述し、クエリ文字列アイテムの存在と正しい形式に依存できるため、アクセスするたびにテストする必要がありません。

注:pre .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();
    }
}
于 2011-05-06T13:43:41.637 に答える