C#ASP.NET QueryString解析器
如果您一直在寻找一种干净利落的方法来解析查询字符串值,我想出了这个:
/// /// Parses the query string and returns a valid value. /// /// /// The query string key. /// The value. protected internal T ParseQueryStringValue(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从URL中提取查询字符串
new Uri(url).Query
鉴于您只处理三种不同的类型,我建议使用三种不同的方法 – 当它们适用于类型约束允许的每个类型参数时,generics方法最佳。
另外,我强烈建议你在int
和DateTime
指定要使用的文化 – 它不应该真正依赖于服务器所处的文化。(如果你有代码来猜测用户的文化,你可以相反。)最后,我还建议支持一组明确指定的DateTime
格式,而不仅仅是TryParse
支持的默认格式。 (我几乎总是使用ParseExact
/ TryParseExact
而不是Parse
/ TryParse
。)
请注意,字符串版本实际上并不需要执行任何操作,因为该value
已经是一个字符串(尽管您当前的代码将“”转换为null
,这可能是您想要的,也可能不是您想要的)。
我编写了以下方法来将QueryString解析为强类型值:
public static bool TryGetValue(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("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。
在我的应用程序中,我一直在使用以下function: –
public static class WebUtil { public static T GetValue(string key, StateBag stateBag, T defaultValue) { object o = stateBag[key]; return o == null ? defaultValue : (T)o; } }
如果未提供参数,则返回所需的缺省值,从defaultValue推断类型,并根据需要引发转换exception。
用法如下: –
var foo = WebUtil.GetValue("foo", ViewState, default(int?));
这是一个陈旧的答案,但我做了以下事情:
string queryString = relayState.Split("?").ElementAt(1); NameValueCollection nvc = HttpUtility.ParseQueryString(queryString);
在我看来,你正在做很多无聊的类型转换。 tempValue变量是您尝试返回的类型的主要变量。 同样在字符串的情况下,值已经是一个字符串,所以只需返回它。
基于Ronalds的答案,我已经更新了自己的查询字符串解析方法。 我使用它的方法是将它作为扩展方法添加到Page对象上,这样我就可以轻松检查查询字符串值和类型,并在页面请求无效时重定向。
扩展方法如下所示:
public static class PageHelpers { public static void RequireOrPermanentRedirect(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("CategoryId", "/"); }
然后我可以编写其余的代码并依赖查询字符串项的存在和正确的格式,所以每次我想访问它时都不必测试它。
注意:如果您使用的是.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(); } }