[英]C# ASP.NET QueryString parser
如果您一直在寻找一种解析查询字符串值的好方法,那么我想出了这个方法:
/// <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);
}
我一直想拥有这样的东西,最终做到正确……至少我是这么认为的……
该代码应该是自我解释的...
任何意见或建议,以使其更好。
解析(如果您不想进行类型转换)的一种简单方法是
HttpUtility.ParseQueryString(queryString);
您可以使用以下命令从URL中提取查询字符串
new Uri(url).Query
鉴于您只能处理三种不同的类型,我建议使用三种不同的方法-泛型方法最好与类型约束所允许的每个类型参数一起使用,这是最好的。
此外,我强烈建议您为int
和DateTime
指定要使用的区域性-它实际上不应取决于服务器碰巧所处的区域性。(如果您有代码来猜测用户的区域性,则可以最后,我还建议您支持一组指定良好的DateTime
格式,而不是默认使用的TryParse
支持的格式。 (我几乎总是使用ParseExact
/ TryParseExact
而不是Parse
/ TryParse
。)
请注意,考虑到该value
已经是一个字符串,字符串版本实际上不需要执行任何操作(尽管您当前的代码会将“”转换为null
,这可能是您想要的,也可能不是您想要的)。
我编写了以下方法来将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
值为true,而int productId
等于5。
对于?productId=hello
的查询字符串, bool
将为false,而int productId
将为0。
对于?noProductId=notIncluded
的查询字符串, bool
将为false,而int productId
将等于0。
这是一个旧答案,但是我已经完成了以下工作:
string queryString = relayState.Split("?").ElementAt(1);
NameValueCollection nvc = HttpUtility.ParseQueryString(queryString);
在我的应用程序中,我一直在使用以下功能:
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?));
在我看来,您正在执行许多不必要的类型转换。 tempValue变量导致您尝试返回的类型。 同样,在字符串的情况下,该值已经是字符串,因此只需返回它即可。
基于Ronalds的答案,我更新了自己的querystring解析方法。 我使用它的方式是将其添加为Page对象上的扩展方法,因此对我来说很容易检查querystring值和类型,并在页面请求无效时重定向。
扩展方法如下所示:
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", "/");
}
然后,我可以编写其余代码,并依靠querystring项目的存在和正确格式,因此我不必在每次访问它时都进行测试。
注意:如果使用的是.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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.