从.NET中的字符串中获取url参数

Bes*_*ska 220 .net c# parameters url parsing

我在.NET中有一个字符串,实际上是一个网址.我想要一种简单的方法来从特定参数中获取值.

通常,我只是使用Request.Params["theThingIWant"],但这个字符串不是来自请求.我可以Uri像这样创建一个新项目:

Uri myUri = new Uri(TheStringUrlIWantMyValueFrom);
Run Code Online (Sandbox Code Playgroud)

我可以myUri.Query用来获取查询字符串......但是我显然必须找到一些分解它的regexy方法.

我是否遗漏了一些明显的东西,或者没有内置的方法来创建某种类型的正则表达式等等?

CZF*_*Fox 459

使用返回ParseQueryStringSystem.Web.HttpUtility类的静态方法NameValueCollection.

Uri myUri = new Uri("http://www.example.com?param1=good&param2=bad");
string param1 = HttpUtility.ParseQueryString(myUri.Query).Get("param1");
Run Code Online (Sandbox Code Playgroud)

查看文档,网址http://msdn.microsoft.com/en-us/library/ms150046.aspx

  • 这似乎没有检测到第一个参数.例如,解析"http://www.google.com/search?q=energy+edge&rls=com.microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1"未检测到参数q (13认同)
  • 您不能使用`HttpUtility.ParseQueryString(string)`解析完整的查询URL!顾名思义,它是解析查询字符串,而不是带有查询参数的URL。如果要执行此操作,则必须先将它用`?'拆分,如下所示:`Url.Split('?')`并使用(根据情况和所需的情况)`[0]`或LINQ来获取最后一个元素`Last()`/`LastOrDefault()`。 (3认同)

Ser*_*jev 46

这可能就是你想要的

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");
Run Code Online (Sandbox Code Playgroud)


als*_*d42 30

如果出于任何原因,您不能或不想使用,这是另一种选择HttpUtility.ParseQueryString().

这构建为对"格式错误"的查询字符串有一定的容忍度,即http://test/test.html?empty=变为具有空值的参数.如果需要,调用者可以验证参数.

public static class UriHelper
{
    public static Dictionary<string, string> DecodeQueryParameters(this Uri uri)
    {
        if (uri == null)
            throw new ArgumentNullException("uri");

        if (uri.Query.Length == 0)
            return new Dictionary<string, string>();

        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));
    }
}
Run Code Online (Sandbox Code Playgroud)

测试

[TestClass]
public class UriHelperTest
{
    [TestMethod]
    public void DecodeQueryParameters()
    {
        DecodeQueryParametersTest("http://test/test.html", new Dictionary<string, string>());
        DecodeQueryParametersTest("http://test/test.html?", new Dictionary<string, string>());
        DecodeQueryParametersTest("http://test/test.html?key=bla/blub.xml", new Dictionary<string, string> { { "key", "bla/blub.xml" } });
        DecodeQueryParametersTest("http://test/test.html?eins=1&zwei=2", new Dictionary<string, string> { { "eins", "1" }, { "zwei", "2" } });
        DecodeQueryParametersTest("http://test/test.html?empty", new Dictionary<string, string> { { "empty", "" } });
        DecodeQueryParametersTest("http://test/test.html?empty=", new Dictionary<string, string> { { "empty", "" } });
        DecodeQueryParametersTest("http://test/test.html?key=1&", new Dictionary<string, string> { { "key", "1" } });
        DecodeQueryParametersTest("http://test/test.html?key=value?&b=c", new Dictionary<string, string> { { "key", "value?" }, { "b", "c" } });
        DecodeQueryParametersTest("http://test/test.html?key=value=what", new Dictionary<string, string> { { "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<string, string>
            {
                { "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<string, string> { { "key", "value,anotherValue" } });
    }

    private static void DecodeQueryParametersTest(string uri, Dictionary<string, string> expected)
    {
        Dictionary<string, string> 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*ter 12

看起来你应该循环遍历值myUri.Query并从那里解析它.

 string desiredValue;
 foreach(string item in myUri.Query.Split('&'))
 {
     string[] parts = item.Replace('?', '').Split('=');
     if(parts[0] == "desiredKey")
     {
         desiredValue = parts[1];
         break;
     }
 }
Run Code Online (Sandbox Code Playgroud)

但是,如果不对一堆格式错误的URL进行测试,我就不会使用此代码.它可能会破坏部分/全部:

  • hello.html?
  • hello.html?valuelesskey
  • hello.html?key=value=hi
  • hello.html?hi=value?&b=c
  • 等等


小智 11

@Andrew和@CZFox

我有同样的错误,发现原因是事实上是一个参数:http://www.example.com?param1而不是param1人们所期望的那个.

通过删除问号之前的所有字符来修复此问题.所以本质上该HttpUtility.ParseQueryString函数只需要一个有效的查询字符串参数,该参数只包含问号之后的字符,如:

HttpUtility.ParseQueryString ( "param1=good&param2=bad" )
Run Code Online (Sandbox Code Playgroud)

我的解决方法:

string RawUrl = "http://www.example.com?param1=good&param2=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" );`
Run Code Online (Sandbox Code Playgroud)


Ami*_*bar 7

您可以仅使用Uri来获取查询字符串列表或查找特定参数。

Uri myUri = new Uri("http://www.example.com?param1=good&param2=bad");
var params = myUri.ParseQueryString();
var specific = myUri.ParseQueryString().Get("param1");
var paramByIndex = myUri.ParseQueryString().Get(2);
Run Code Online (Sandbox Code Playgroud)

您可以从这里找到更多信息:https://learn.microsoft.com/en-us/dotnet/api/system.uri ?view=net-5.0


tom*_*msv 5

您也可以使用以下解决方法来处理第一个参数:

var param1 =
    HttpUtility.ParseQueryString(url.Substring(
        new []{0, url.IndexOf('?')}.Max()
    )).Get("param1");
Run Code Online (Sandbox Code Playgroud)