我很好奇大家在ASP.NET中是如何处理/抽象QueryString的。在我们的一些Web应用程序中,我看到这种代码遍布整个站点:
int val = 0;
if(Request.QueryString["someKey"] != null)
{
val = Convert.ToInt32(Request.QueryString["someKey"]);
}
有哪些更好的方式来处理这种恶心的东西?
我倾向于将它们抽象成属性的思路。 例如:
public int age {
get
{
if (Request.QueryString["Age"] == null)
return 0;
else
return int.Parse(Request.QueryString["Age"]);
}
}
如果你想的话,可以添加更多的验证。但是我喜欢用这种方式来包装所有的查询字符串变量。
编辑:--- 正如另一个发布者指出的那样,你必须在每个页面上创建这些属性。我的回答是不需要的。你可以在一个名为 "QueryStrings" 的类中创建这些属性。然后在你想要访问你的查询字符串的每个页面中实例化这个类,然后你只需要像这样做:
var queryStrings = new QueryStrings();
var age = queryStrings.age;
通过这种方式,您可以将访问和处理每种类型的查询变量的所有逻辑封装在一个可维护的单一位置中。
编辑2: --- 由于它是类的实例,您还可以使用依赖注入将QueryStrings类注入到您使用它的每个地方。 StructureMap 做得很好。这还允许您模拟QueryStrings类并注入它,如果您想进行自动化单元测试,则比ASP.Net的Request对象更容易模拟。
有一件事是你没有捕获空值。你可能有一个像这样的url:“http://example.com?someKey=&anotherKey=12345”,在这种情况下,“someKey”参数值为“”(空)。您可以使用string.IsNullOrEmpty()来检查null和empty状态。
我还会更改“someKey”以存储在变量中。这样,您就不会在多个位置重复字面字符串。这使得维护更加容易。
int val = 0;
string myKey = "someKey";
if (!string.IsNullOrEmpty(Request.QueryString[myKey]))
{
val = int.Parse(Request.QueryString[myKey]);
}
int val = 0; string myKey = "someKey"; string strVal = HttpContext.Current.Request.QueryString[myKey]; if(!String.IsNullOrEmpty(strVal) && !int.TryParse(strVal, out val)){ val = 0; }
- GFoley83/// <summary>
/// Gets the given querystring parameter as a the specified value <see cref="Type"/>
/// </summary>
/// <typeparam name="T">The type to convert the querystring value to</typeparam>
/// <param name="name">Querystring parameter name</param>
/// <param name="defaultValue">Default value to return if parameter not found</param>
/// <returns>The value as the specified <see cref="Type"/>, or the default value if not found</returns>
public static T GetValueFromQueryString<T>(string name, T defaultValue) where T : struct
{
if (String.IsNullOrEmpty(name) || HttpContext.Current == null || HttpContext.Current.Request == null)
return defaultValue;
try
{
return (T)Convert.ChangeType(HttpContext.Current.Request.QueryString[name], typeof(T));
}
catch
{
return defaultValue;
}
}
/// <summary>
/// Gets the given querystring parameter as a the specified value <see cref="Type"/>
/// </summary>
/// <typeparam name="T">The type to convert the querystring value to</typeparam>
/// <param name="name">Querystring parameter name</param>
/// <returns>The value as the specified <see cref="Type"/>, or the types default value if not found</returns>
public static T GetValueFromQueryString<T>(string name) where T : struct
{
return GetValueFromQueryString(name, default(T));
}
字符串类型必须是非空值类型,才能在泛型中用作参数'T'。
- Drag and Drop编写某种帮助方法(库)来处理它...
public static void GetInt(this NameValueCollection nvCol, string key, out int keyValue, int defaultValue)
{
if (string.IsNullOrEmpty(nvCol[key]) || !int.TryParse(nvCol[key], out keyValue))
keyValue = defaultValue;
}
或者类似这样的东西...
我认为获取查询字符串的最佳方法如下:
如果未找到查询字符串,则val
的值将为0
。
int val = 0;
int.TryParse(Request.QueryString["someKey"], out val);
我们一直在使用常量来将所有这些“松散”的键放在一个中心位置:
public class Constants
{
public class QueryString
{
public const string PostID = "pid";
public const string PostKey = "key";
}
public class Cookie
{
public const string UserID = "mydomain.com-userid";
}
public class Cache
{
public const string PagedPostList = "PagedPostList-{0}-{1}";
}
public class Context
{
public const string PostID = "PostID";
}
public class Security
{
public const RoleAdministrator = "Administrator";
}
}
这样,你就可以轻松使用以下方式访问所需的常量:
public void Index()
{
if (Request[Constants.QueryString.PostKey] == "eduncan911")
{
// do something
}
}
public object GetPostsFromCache(int postID, int userID)
{
String cacheKey = String.Format(
Constants.Cache.PagedPostList
, userID
, postID);
return Cache[cacheKey] as IList<Post>;
}