【问题标题】:Get URL parameters from a string in .NET从 .NET 中的字符串获取 URL 参数
【发布时间】:2010-10-14 04:17:12
【问题描述】:

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

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

Uri myUri = new Uri(TheStringUrlIWantMyValueFrom);

我可以使用myUri.Query 来获取查询字符串...但是我显然必须找到一些正则表达式来拆分它。

我是否遗漏了一些明显的东西,或者除了创建某种正则表达式等之外,没有内置的方法可以做到这一点?

【问题讨论】:

    标签: c# .net url parsing parameters


    【解决方案1】:

    看起来您应该遍历 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

    【讨论】:

      【解决方案2】:

      使用返回NameValueCollectionSystem.Web.HttpUtility类的静态ParseQueryString方法。

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

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

      【讨论】:

      • 这似乎没有检测到第一个参数。例如解析“google.com/…”没有检测到参数q
      • @Andrew 我确认。这很奇怪(错误?)。你仍然可以使用HttpUtility.ParseQueryString(myUri.Query).Get(0),它会提取第一个参数。 `
      • 任何 .NET 工具来构建参数化查询 url?
      • 您无法解析带有HttpUtility.ParseQueryString(string) 的完整查询URL!顾名思义,它是解析查询字符串,而不是带有查询参数的 URL。如果你想这样做,你必须先用?像这样分割它:Url.Split('?')并使用(取决于情况和你需要什么)[0]或LINQ的Last()/LastOrDefault()获取最后一个元素。
      • 我自己试用时,签名似乎已更改为:HttpUtility.ParseQueryString(uri.Query).GetValues("param1").First()
      【解决方案3】:

      使用.NET Reflector查看System.Web.HttpValueCollectionFillFromString方法。这为您提供了 ASP.NET 用于填充 Request.QueryString 集合的代码。

      【讨论】:

        【解决方案4】:

        这可能就是你想要的

        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");
        

        【讨论】:

          【解决方案5】:

          @Andrew 和@CZFox

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

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

          HttpUtility.ParseQueryString ( "param1=good&param2=bad" )
          

          我的解决方法:

          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" );`
          

          【讨论】:

          • 实例化 URI 时出现错误“无效的 URI:无法确定 URI 的格式。”我不认为这个解决方案能按预期工作。
          • @PaulMatthews,你是对的。在给出这个解决方案时,我使用的是较旧的 .net 框架 2.0。为了确认您的声明,我将此解决方案复制并粘贴到 Joseph Albahara 的 LINQPad v2 中,并收到您提到的相同错误。
          • @PaulMatthews,要修复,删除读取 Uri myUri = new Uri( RawUrl ); 的行并将 RawUrl 传递给最后一条语句,如下所示: string param1 = HttpUtility.ParseQueryString( RawUrl ).Get( "param2" );
          • 是的,它仅解析查询字符串部分的事实在名称和文档中。这不是一个错误。我什至不确定他们如何才能使它更清楚。 ParseQueryString 解析查询字符串。
          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

            如果出于某种原因您不能或不想使用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));
                }
            }
            

            测试

            [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);
                    }
                }
            }
            

            【讨论】:

            • 有助于 Xamarin 项目,其中 HttpUtility 不可用
            • 这是一个非常有用的扩展,也可以适用于部分 URI。我建议将 Uri.UnescapeDataString() 添加到参数值或将方法重命名为“解码”以外的其他名称,如果它们实际上没有被解码。 ?empty= 不是格式错误的查询字符串。它只有一个带有空字符串作为值的参数。这是完全正常的,所以感谢您考虑到这一点。
            • 这与HttpUtility.ParseQueryString() 的行为不匹配,因为它没有对值进行正确解码。正如预期结果测试用例 { "startPage", "1%22" } 中所指出的,该值仍然是百分比编码的,但如果它被 HttpUtility 类解析,它将是 1"
            【解决方案8】:

            如果您想在默认页面上获取您的 QueryString。默认页面表示您当前的页面 url。 你可以试试这段代码:

            string paramIl = HttpUtility.ParseQueryString(this.ClientQueryString).Get("city");
            

            【讨论】:

              【解决方案9】:
              HttpContext.Current.Request.QueryString.Get("id");
              

              【讨论】:

              • 如何在字符串中使用它
              【解决方案10】:

              或者如果您不知道 URL(为了避免硬编码,请使用 AbsoluteUri

              示例 ...

                      //get the full URL
                      Uri myUri = new Uri(Request.Url.AbsoluteUri);
                      //get any parameters
                      string strStatus = HttpUtility.ParseQueryString(myUri.Query).Get("status");
                      string strMsg = HttpUtility.ParseQueryString(myUri.Query).Get("message");
                      switch (strStatus.ToUpper())
                      {
                          case "OK":
                              webMessageBox.Show("EMAILS SENT!");
                              break;
                          case "ER":
                              webMessageBox.Show("EMAILS SENT, BUT ... " + strMsg);
                              break;
                      }
              

              【讨论】:

                【解决方案11】:

                我用过它,它运行良好

                <%=Request.QueryString["id"] %>
                

                【讨论】:

                • 从一个字符串不是查询字符串
                【解决方案12】:

                这实际上非常简单,而且对我有用:)

                        if (id == "DK")
                        {
                            string longurl = "selectServer.aspx?country=";
                            var uriBuilder = new UriBuilder(longurl);
                            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
                            query["country"] = "DK";
                
                            uriBuilder.Query = query.ToString();
                            longurl = uriBuilder.ToString();
                        } 
                

                【讨论】:

                  【解决方案13】:

                  对于任何想要遍历字符串中的所有查询字符串的人

                          foreach (var item in new Uri(urlString).Query.TrimStart('?').Split('&'))
                          {
                              var subStrings = item.Split('=');
                  
                              var key = subStrings[0];
                              var value = subStrings[1];
                  
                              // do something with values
                          }
                  

                  【讨论】:

                    【解决方案14】:

                    单行LINQ解决方案:

                    Dictionary<string, string> ParseQueryString(string query)
                    {
                        return query.Replace("?", "").Split('&').ToDictionary(pair => pair.Split('=').First(), pair => pair.Split('=').Last());
                    }
                    

                    【讨论】:

                      【解决方案15】:

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

                      Uri myUri = new Uri("http://www.example.com?param1=good&param2=bad");
                      var params = myUri.ParseQueryString();
                      var specific = myUri.ParseQueryString().Get("spesific");
                      var paramByIndex = = myUri.ParseQueryString().Get(1);
                      

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

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2011-05-08
                        • 2012-07-13
                        • 2017-07-20
                        • 2016-12-03
                        • 2019-02-02
                        相关资源
                        最近更新 更多