如何测试 Request.QueryString[] 变量?

发布于 2024-07-10 03:12:56 字数 497 浏览 6 评论 0原文

我经常使用 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[]

I frequently make use of Request.QueryString[] variables.

In my Page_load I often do things like:

       int id = -1;

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

        DoSomethingSpectacularNow(id);

It all seems a bit clunky and rubbish. How do you deal with your Request.QueryString[]s?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

轮廓§ 2024-07-17 03:12:57

哎呀,这是一个业力风险...

我有一个 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;
}

Eeee this is a karma risk...

I have a DRY unit-testable abstraction because, well, because there were too many querystring variables to keep on in a legacy conversion.

The code below is from a utility class whose constructor requires a NameValueCollection input (this.source) and the string array "keys" is because the legacy app was rather organic and had developed the possibility for several different strings to be a potential input key. However I kind of like the extensibility. This method inspects the collection for the key and returns it in the datatype required.

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;
}
甜宝宝 2024-07-17 03:12:57

我实际上有一个实用程序类,它使用泛型来“包装”会话,它为我完成所有“繁重工作”,我还有一些几乎相同的用于处理 QueryString 值的东西。

这有助于消除(通常是大量)检查的代码重复。

例如:

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

注意:

这显然使用了静态,有些人不喜欢静态,因为它会影响测试代码..您可以轻松地重构为基于实例和您需要的任何接口工作的东西。.我只是认为静态示例是最轻的。

希望这能有所帮助/引人深思。

I actually have a utility class that uses Generics to "wrap" session, which does all of the "grunt work" for me, I also have something almost identical for working with QueryString values.

This helps remove the code dupe for the (often numerous) checks..

For example:

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

NOTE:

This obviously makes use of statics, which some people don't like because of the way it can impact test code.. You can easily refactor into something that works based on instances and any interfaces you require.. I just think the statics example is the lightest.

Hope this helps/gives food for thought.

鲸落 2024-07-17 03:12:57

我确实为每个函数都有函数(实际上它是一个小类,有很多静态数据):

  • GetIntegerFromQuerystring(val)
  • GetIntegerFromPost(val)
  • .... code>

如果失败则返回 -1(这对我来说几乎总是可以的,我还有一些其他负数函数)。

Dim X as Integer = GetIntegerFromQuerystring("id")
If x = -1 Then Exit Sub

I do have functions for each (actually it's one small class, with lots of statics):

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

It returns -1 if fails (which is almost always OK for me, I have some other functions for negative numbers as well).

Dim X as Integer = GetIntegerFromQuerystring("id")
If x = -1 Then Exit Sub
悲欢浪云 2024-07-17 03:12:57

我修改了 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;

I modified Bryan Watts' answer so that if the param your asking does not exist and you have specified a nullable type it will return 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);
    }

You can now do this :

Request.QueryString.GetValue<int?>(paramName) ?? 10;
月下凄凉 2024-07-17 03:12:56

下面是一个扩展方法,允许您编写如下代码:

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

Below is an extension method that will allow you to write code like this:

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

It makes use of TypeDescriptor to perform the conversion. Based on your needs, you could add an overload which takes a default value instead of throwing an exception:

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);
}
滥情空心 2024-07-17 03:12:56

使用 int.TryParse 代替来摆脱 try-catch 块:

if (!int.TryParse(Request.QueryString["id"], out id))
{
  // error case
}

Use int.TryParse instead to get rid of the try-catch block:

if (!int.TryParse(Request.QueryString["id"], out id))
{
  // error case
}
穿透光 2024-07-17 03:12:56

试试这个家伙...

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

然后你将能够通过...轻松地在他中搜索字符串...

keys.Contains("someKey")

Try this dude...

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

Then you will be able to search the guy for a string real easy via...

keys.Contains("someKey")
逆流 2024-07-17 03:12:56

我正在使用一个小辅助方法:

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

I'm using a little helper method:

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

This method allows me to read values from the query string in the following way:

int id = QueryString("id", 0);
眼泪淡了忧伤 2024-07-17 03:12:56

一方面,请使用 int.TryParse 代替......

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

当然,假设“不存在”应该具有与“不是整数”相同的结果。

编辑:在其他情况下,当您无论如何都要使用请求参数作为字符串时,我认为验证它们是否存在绝对是个好主意。

Well for one thing use int.TryParse instead...

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

That assumes that "not present" should have the same result as "not an integer" of course.

EDIT: In other cases, when you're going to use request parameters as strings anyway, I think it's definitely a good idea to validate that they're present.

往日 2024-07-17 03:12:56

您也可以使用下面的扩展方法,并像这样

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

You can use the extension methods below as well and do like this

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

}

// Extension methods

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;
}
萌酱 2024-07-17 03:12:56
if(!string.IsNullOrEmpty(Request.QueryString["id"]))
{
//querystring contains id
}
if(!string.IsNullOrEmpty(Request.QueryString["id"]))
{
//querystring contains id
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文