我在.NET中有一个字符串,实际上是一个网址.我想要一种简单的方法来从特定参数中获取值.
通常,我只是使用Request.Params["theThingIWant"]
,但这个字符串不是来自请求.我可以Uri
像这样创建一个新项目:
Uri myUri = new Uri(TheStringUrlIWantMyValueFrom);
我可以myUri.Query
用来获取查询字符串......但是我显然必须找到一些分解它的regexy方法.
我是否遗漏了一些明显的东西,或者没有内置的方法来创建某种类型的正则表达式等等?
使用返回ParseQueryString
的System.Web.HttpUtility
类的静态方法NameValueCollection
.
Uri myUri = new Uri("http://www.example.com?param1=good¶m2=bad"); string param1 = HttpUtility.ParseQueryString(myUri.Query).Get("param1");
查看文档,网址为http://msdn.microsoft.com/en-us/library/ms150046.aspx
这可能就是你想要的
var uri = new Uri("http://domain.test/Default.aspx?var1=true&var2=test&var3=3"); var query = HttpUtility.ParseQueryString(uri.Query); var var2 = query.Get("var2");
如果出于任何原因,您不能或不想使用,这是另一种选择HttpUtility.ParseQueryString()
.
这构建为对"格式错误"的查询字符串有一定的容忍度,即http://test/test.html?empty=
变为具有空值的参数.如果需要,调用者可以验证参数.
public static class UriHelper { public static DictionaryDecodeQueryParameters(this Uri uri) { if (uri == null) throw new ArgumentNullException("uri"); if (uri.Query.Length == 0) return new Dictionary (); return uri.Query.TrimStart('?') .Split(new[] { '&', ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(parameter => parameter.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries)) .GroupBy(parts => parts[0], parts => parts.Length > 2 ? string.Join("=", parts, 1, parts.Length - 1) : (parts.Length > 1 ? parts[1] : "")) .ToDictionary(grouping => grouping.Key, grouping => string.Join(",", grouping)); } }
测试
[TestClass] public class UriHelperTest { [TestMethod] public void DecodeQueryParameters() { DecodeQueryParametersTest("http://test/test.html", new Dictionary()); DecodeQueryParametersTest("http://test/test.html?", new Dictionary ()); DecodeQueryParametersTest("http://test/test.html?key=bla/blub.xml", new Dictionary { { "key", "bla/blub.xml" } }); DecodeQueryParametersTest("http://test/test.html?eins=1&zwei=2", new Dictionary { { "eins", "1" }, { "zwei", "2" } }); DecodeQueryParametersTest("http://test/test.html?empty", new Dictionary { { "empty", "" } }); DecodeQueryParametersTest("http://test/test.html?empty=", new Dictionary { { "empty", "" } }); DecodeQueryParametersTest("http://test/test.html?key=1&", new Dictionary { { "key", "1" } }); DecodeQueryParametersTest("http://test/test.html?key=value?&b=c", new Dictionary { { "key", "value?" }, { "b", "c" } }); DecodeQueryParametersTest("http://test/test.html?key=value=what", new Dictionary { { "key", "value=what" } }); DecodeQueryParametersTest("http://www.google.com/search?q=energy+edge&rls=com.microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1%22", new Dictionary { { "q", "energy+edge" }, { "rls", "com.microsoft:en-au" }, { "ie", "UTF-8" }, { "oe", "UTF-8" }, { "startIndex", "" }, { "startPage", "1%22" }, }); DecodeQueryParametersTest("http://test/test.html?key=value;key=anotherValue", new Dictionary { { "key", "value,anotherValue" } }); } private static void DecodeQueryParametersTest(string uri, Dictionary expected) { Dictionary parameters = new Uri(uri).DecodeQueryParameters(); Assert.AreEqual(expected.Count, parameters.Count, "Wrong parameter count. Uri: {0}", uri); foreach (var key in expected.Keys) { Assert.IsTrue(parameters.ContainsKey(key), "Missing parameter key {0}. Uri: {1}", key, uri); Assert.AreEqual(expected[key], parameters[key], "Wrong parameter value for {0}. Uri: {1}", parameters[key], uri); } } }
看起来你应该循环遍历值myUri.Query
并从那里解析它.
string desiredValue; foreach(string item in myUri.Query.Split('&')) { string[] parts = item.Replace('?', '').Split('='); if(parts[0] == "desiredKey") { desiredValue = parts[1]; break; } }
但是,如果不对一堆格式错误的URL进行测试,我就不会使用此代码.它可能会破坏部分/全部:
hello.html?
hello.html?valuelesskey
hello.html?key=value=hi
hello.html?hi=value?&b=c
等等
@Andrew和@CZFox
我有同样的错误,发现原因是事实上是一个参数:http://www.example.com?param1
而不是param1
人们所期望的那个.
通过删除问号之前的所有字符来修复此问题.所以本质上该HttpUtility.ParseQueryString
函数只需要一个有效的查询字符串参数,该参数只包含问号之后的字符,如:
HttpUtility.ParseQueryString ( "param1=good¶m2=bad" )
我的解决方法:
string RawUrl = "http://www.example.com?param1=good¶m2=bad"; int index = RawUrl.IndexOf ( "?" ); if ( index > 0 ) RawUrl = RawUrl.Substring ( index ).Remove ( 0, 1 ); Uri myUri = new Uri( RawUrl, UriKind.RelativeOrAbsolute); string param1 = HttpUtility.ParseQueryString( myUri.Query ).Get( "param1" );`