C# 你如何测试你的 Request.QueryString[] 变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/349742/
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
How do you test your Request.QueryString[] variables?
提问by inspite
I frequently make use of Request.QueryString[]
variables.
我经常使用Request.QueryString[]
变量。
In my Page_load
I often do things like:
在我的Page_load
我经常做这样的事情:
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?
这一切似乎有点笨拙和垃圾。你怎么处理你的Request.QueryString[]
s?
采纳答案by Bryan Watts
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:
它利用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);
}
回答by VVS
Use int.TryParse instead to get rid of the try-catch block:
改用 int.TryParse 来摆脱 try-catch 块:
if (!int.TryParse(Request.QueryString["id"], out id))
{
// error case
}
回答by Jon Skeet
Well for one thing use int.TryParse instead...
好吧,一方面使用 int.TryParse 代替...
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.
编辑:在其他情况下,当您无论如何要使用请求参数作为字符串时,我认为验证它们是否存在绝对是个好主意。
回答by Jon Skeet
if(!string.IsNullOrEmpty(Request.QueryString["id"]))
{
//querystring contains id
}
回答by dr. evil
I do have functions for each (actually it's one small class, with lots of statics):
我确实有每个函数(实际上它是一个小类,有很多静态):
GetIntegerFromQuerystring(val)
GetIntegerFromPost(val)
....
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).
如果失败,它返回-1(这对我来说几乎总是可以的,我还有一些其他的负数函数)。
Dim X as Integer = GetIntegerFromQuerystring("id")
If x = -1 Then Exit Sub
回答by M4N
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);
回答by annakata
Eeee this is a karma risk...
Eeee这是一个业力风险......
I have a DRY unit-testable abstraction because, well, because there were too many querystring variables to keep on in a legacy conversion.
我有一个 DRY 单元可测试抽象,因为有太多的查询字符串变量无法继续进行遗留转换。
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.
下面的代码来自一个实用程序类,它的构造函数需要 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;
}
回答by Rob Cooper
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.
我实际上有一个实用程序类,它使用泛型来“包装”会话,它为我完成所有“繁重的工作”,我也有一些几乎相同的东西来处理 QueryString 值。
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.
希望这有助于/提供思考。
回答by terjetyl
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;
}
回答by W3Max
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 :
我修改了 Bryan Watts 的答案,以便如果您询问的参数不存在并且您指定了可空类型,它将返回 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;