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

Posted

技术标签:

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

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

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

Uri myUri = new Uri(TheStringUrlIWantMyValueFrom);

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

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

【问题讨论】:

【参考方案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

【讨论】:

以上是关于从 .NET 中的字符串获取 URL 参数的主要内容,如果未能解决你的问题,请参考以下文章

如何从 C# 中的相对 URL 字符串中获取参数?

如何从 Swift 3 xcode8 的 UIWebView 中的 url 获取查询字符串参数?

Javasrcipt中从一个url或者从一个字符串中获取参数值得方法

如何从asp.net中的paypal(Sandbox)获取返回url中的参数

如何从谷歌文本到 PHP 中的语音 API 中的 URL 参数获取性别声音?

asp截取url中的字符