50

Request.QueryString[]私は頻繁に変数を利用します。

私のPage_load中で私はよく次のようなことをします:

       int id = -1;

        if (Request.QueryString["id"] != null) {
            try
            {
                id = int.Parse(Request.QueryString["id"]);
            }
            catch
            {
                // deal with it
            }
        }

        DoSomethingSpectacularNow(id);

それはすべて少し不格好でゴミのようです。あなたはあなたのをどのように扱いますRequest.QueryString[]か?

4

11 に答える 11

52

以下は、次のようなコードを記述できる拡張メソッドです。

int id = request.QueryString.GetValue<int>("id");
DateTime date = request.QueryString.GetValue<DateTime>("date");

を利用TypeDescriptorして変換を実行します。必要に応じて、例外をスローする代わりにデフォルト値を取るオーバーロードを追加できます。

public static T GetValue<T>(this NameValueCollection collection, string key)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    var value = collection[key];

    if(value == null)
    {
        throw new ArgumentOutOfRangeException("key");
    }

    var converter = TypeDescriptor.GetConverter(typeof(T));

    if(!converter.CanConvertFrom(typeof(string)))
    {
        throw new ArgumentException(String.Format("Cannot convert '{0}' to {1}", value, typeof(T)));
    }

    return (T) converter.ConvertFrom(value);
}
于 2008-12-08T15:11:00.677 に答える
34

代わりにint.TryParseを使用して、try-catchブロックを削除します。

if (!int.TryParse(Request.QueryString["id"], out id))
{
  // error case
}
于 2008-12-08T14:42:01.360 に答える
19

この男を試してみてください...

List<string> keys = new List<string>(Request.QueryString.AllKeys);

次に、文字列を介して男を簡単に検索できます...

keys.Contains("someKey")
于 2010-09-29T19:52:43.993 に答える
17

私は小さなヘルパーメソッドを使用しています:

public static int QueryString(string paramName, int defaultValue)
{
    int value;
    if (!int.TryParse(Request.QueryString[paramName], out value))
        return defaultValue;
    return value;
}

このメソッドを使用すると、次の方法でクエリ文字列から値を読み取ることができます。

int id = QueryString("id", 0);
于 2008-12-08T14:50:23.137 に答える
10

一つには、代わりにint.TryParseを使用してください...

int id;
if (!int.TryParse(Request.QueryString["id"], out id))
{
    id = -1;
}

もちろん、「存在しない」は「整数ではない」と同じ結果になるはずです。

編集:他の場合、とにかくリクエストパラメータを文字列として使用する場合は、それらが存在することを検証することは間違いなく良い考えだと思います。

于 2008-12-08T14:43:01.840 に答える
9

以下の拡張メソッドも使用でき、このようにすることができます

int? id = Request["id"].ToInt();
if(id.HasValue)
{

}

// 拡張メソッド

public static int? ToInt(this string input) 
{
    int val;
    if (int.TryParse(input, out val))
        return val;
    return null;
}

public static DateTime? ToDate(this string input)
{
    DateTime val;
    if (DateTime.TryParse(input, out val))
        return val;
    return null;
}

public static decimal? ToDecimal(this string input)
{
    decimal val;
    if (decimal.TryParse(input, out val))
        return val;
    return null;
}
于 2008-12-08T14:58:24.947 に答える
4
if(!string.IsNullOrEmpty(Request.QueryString["id"]))
{
//querystring contains id
}
于 2008-12-08T14:44:52.150 に答える
1

Bryan Wattsの回答を変更して、要求するパラメータが存在せず、null許容型を指定した場合にnullを返すようにしました。

public static T GetValue<T>(this NameValueCollection collection, string key)
    {
        if (collection == null)
        {
            return default(T);
        }

        var value = collection[key];

        if (value == null)
        {
           return default(T);
        }

        var type = typeof(T);

        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            type = Nullable.GetUnderlyingType(type);
        }

        var converter = TypeDescriptor.GetConverter(type);

        if (!converter.CanConvertTo(value.GetType()))
        {
            return default(T);
        }

        return (T)converter.ConvertTo(value, type);
    }

あなたは今これを行うことができます:

Request.QueryString.GetValue<int?>(paramName) ?? 10;
于 2009-10-19T19:00:00.663 に答える
1

私はそれぞれに関数を持っています(実際には、それはたくさんの静力学を持つ1つの小さなクラスです):

  • GetIntegerFromQuerystring(val)
  • GetIntegerFromPost(val)
  • ....

失敗した場合は-1を返します(これはほとんどの場合問題ありません。負の数に対しても他の関数がいくつかあります)。

Dim X as Integer = GetIntegerFromQuerystring("id")
If x = -1 Then Exit Sub
于 2008-12-08T14:49:19.440 に答える
1

ええ、これはカルマ リスクです...

クエリ文字列変数が多すぎてレガシー変換を維持できないため、DRY 単体テスト可能な抽象化を使用しています。

以下のコードは、コンストラクターが NameValueCollection 入力 (this.source) を必要とするユーティリティ クラスからのものであり、文字列配列 "keys" は、従来のアプリがかなり有機的であり、いくつかの異なる文字列が潜在的な入力キーになる可能性を開発したためです。しかし、私は拡張性が好きです。このメソッドは、キーのコレクションを検査し、必要なデータ型で返します。

private T GetValue<T>(string[] keys)
{
    return GetValue<T>(keys, default(T));
}

private T GetValue<T>(string[] keys, T vDefault)
{
    T x = vDefault;

    string v = null;

    for (int i = 0; i < keys.Length && String.IsNullOrEmpty(v); i++)
    {
        v = this.source[keys[i]];
    }

    if (!String.IsNullOrEmpty(v))
    {
        try
        {
            x = (typeof(T).IsSubclassOf(typeof(Enum))) ? (T)Enum.Parse(typeof(T), v) : (T)Convert.ChangeType(v, typeof(T));
        }
        catch(Exception e)
        {
            //do whatever you want here
        }
    }

    return x;
}
于 2008-12-08T14:54:00.540 に答える
1

私は実際にジェネリックを使用してセッションを「ラップ」するユーティリティクラスを持っています。これは私にとってすべての「面倒な作業」を行います。

これは、(多くの場合、多数の) チェックのコード重複を取り除くのに役立ちます..

例えば:

public class QueryString
{
    static NameValueCollection QS
    {
        get
        {
            if (HttpContext.Current == null)
                throw new ApplicationException("No HttpContext!");

            return HttpContext.Current.Request.QueryString;
        }
    }

    public static int Int(string key)
    {
        int i; 
        if (!int.TryParse(QS[key], out i))
            i = -1; // Obviously Change as you see fit.
        return i;
    }

    // ... Other types omitted.
}

// And to Use..
void Test()
{
    int i = QueryString.Int("test");
}

ノート:

これは明らかに静的を利用しますが、テストコードに影響を与える可能性があるため、一部の人は好まない..インスタンスと必要なインターフェースに基づいて機能するものに簡単にリファクタリングできます..静的の例は最も軽い。

これが役立つことを願っています/思考の糧を与えます.

于 2008-12-08T14:57:17.803 に答える