.NETの文字列からURLパラメータを取得する


239

.NETには実際にはURLである文字列があります。特定のパラメーターから値を取得する簡単な方法が必要です。

通常はを使用しますRequest.Params["theThingIWant"]が、この文字列はリクエストからのものではありません。次のUriような新しいアイテムを作成できます。

Uri myUri = new Uri(TheStringUrlIWantMyValueFrom);

myUri.Queryクエリ文字列を取得するために使用できます...しかし、どうやらそれを分割するためのいくつかのregexy方法を見つける必要があります。

私は明らかなものを欠いていますか、それとも何かの正規表現を作成する以外にこれを行うための組み込みの方法はありませんか?

回答:


494

を返すクラスの静的ParseQueryStringメソッドを使用System.Web.HttpUtilityしますNameValueCollection

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にあるドキュメントを確認してください


14
これは最初のパラメータを検出していないようです。たとえば、「google.com/…」を解析してもパラメーターqは検出されません
Andrew Shepherd

@Andrew確認しました。奇妙です(バグ?)。あなたはまだ使用できますHttpUtility.ParseQueryString(myUri.Query).Get(0)が、最初のパラメータを抽出します。`
Mariusz Pawelski、2011

パラメータ化されたクエリURLを作成する.NETツールはありますか?
Shimmy Weitzhandler

6
HttpUtility.ParseQueryString(string)!で完全なクエリURLを解析することはできません。名前が示すように、クエリパラメータを含むURLではなく、クエリ文字列を解析します。それを行う場合は、最初に次の?ように分割する必要がUrl.Split('?')あります。最後の要素を(状況と必要なものに応じて)[0]またはLINQのLast()/ を使用して取得しますLastOrDefault()
Kosiek

1
これを自分triallingすると、署名がこれに変更されているように見えます:HttpUtility.ParseQueryString(uri.Query).GetValues(「パラメータ1」)ファースト()。
上院議員

48

これはおそらくあなたが望むものです

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

34

何らかの理由でを使用できない、または使用したくない場合の別の方法を次に示します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);
        }
    }
}

HttpUtilityが利用できないXamarinプロジェクトに役立ちます
Artemious

12

@Andrewと@CZFox

私は、同じバグがありましたし、原因は1が実際にあるそのパラメータであることが判明:http://www.example.com?param1及びませんparam1 1が期待するものです。

前にすべての文字を削除し、疑問符を含めることで、この問題は修正されます。したがって、本質的には、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を使用していました。確認のために、私はこのソリューションをジョセフアルバハラによってLINQPad v2にコピーアンドペーストし、あなたが述べたのと同じエラーを受け取りました。
Mo Gauvin 2013年

@PaulMatthews、修正するには、Uri myUri = new Uri(RawUrl);を読み取る行を削除します。次のように、RawUrlを最後のステートメントに渡すだけです。string param1 = HttpUtility.ParseQueryString(RawUrl).Get( "param2");
Mo Gauvin 2013年

ええ、クエリ文字列部分のみを解析するという事実は、名前とドキュメントにあります。バグではありません。彼らがどのようにそれをより明確にすることができるのかさえ私にはわかりません。ParseQueryStringクエリ文字列を解析します。
PandaWood

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

ただし、不正なURLの束でテストしないと、このコードは使用しません。これらの一部またはすべてで壊れる可能性があります。

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

4

次の回避策を使用して、最初のパラメーターを操作することもできます。

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

2

.NET Reflectorを使用してのFillFromStringメソッドを表示しますSystem.Web.HttpValueCollection。これにより、ASP.NETがRequest.QueryStringコレクションの入力に使用するコードが提供されます。


1

または、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;
        }

0

デフォルトページのQueryStringを取得する場合。デフォルトページは、現在のページのURLを意味します。あなたはこのコードを試すことができます:

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

0

これは実際には非常にシンプルで、私にとってはうまくいきました:)

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

0

文字列からすべてのクエリ文字列をループしたい人のために

        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
        }


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.