.NET의 문자열에서 URL 매개 변수 가져 오기


239

.NET에는 실제로 URL 인 문자열이 있습니다. 특정 매개 변수에서 값을 얻는 쉬운 방법을 원합니다.

일반적으로을 사용 Request.Params["theThingIWant"]하지만이 문자열은 요청에서 온 것이 아닙니다. 다음 Uri과 같이 새 항목을 만들 수 있습니다 .

Uri myUri = new Uri(TheStringUrlIWantMyValueFrom);

myUri.Query쿼리 문자열을 얻는 데 사용할 수 있지만 ... 분명한 정규식 방법을 찾아야합니다.

나는 명백한 것을 놓치고 있습니까, 아니면 어떤 종류의 정규 표현식을 만드는 짧은 방법을 수행 할 수있는 방법이 있습니까?

답변:


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

@ 앤드류 확인합니다. 이상합니다 (버그?). 여전히 coul을 사용 HttpUtility.ParseQueryString(myUri.Query).Get(0)하고 첫 번째 매개 변수를 추출합니다. `
Mariusz Pawelski

매개 변수화 된 쿼리 URL을 작성하는 .NET 도구?
Shimmy Weitzhandler

6
HttpUtility.ParseQueryString(string)!로 전체 검색어 URL을 구문 분석 할 수 없습니다 . 이름에서 알 수 있듯이 쿼리 매개 변수가있는 URL이 아닌 쿼리 문자열을 구문 분석해야합니다. 그것을 원한다면 먼저 ?다음 Url.Split('?')과 같이 분할해야합니다 (상황과 필요한 것에 따라) [0]또는 LINQ Last()/를 사용하여 마지막 요소를 가져옵니다 LastOrDefault().
Kosiek

1
이에게 자신을 trialling 때, 서명이 변경 것으로 나타납니다 HttpUtility.ParseQueryString (uri.Query) .GetValues ( "PARAM1") () 첫째.
상원 의원

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

: 나는 같은 버그를했다 및 매개 변수 하나가 사실이라고 할 원인을 발견 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 형식을 확인할 수 없습니다"라는 오류가 발생합니다. 이 솔루션이 의도 한대로 작동하지 않는다고 생각합니다.
Paul Matthews

@PaulMatthews, 당신은 맞습니다. 이 솔루션을 제공 할 당시에는 이전 .net 프레임 워크 2.0을 사용하고있었습니다. 귀하의 진술을 확인하기 위해 Joseph Albahara가이 솔루션을 LINQPad v2에 복사하여 붙여 넣었으며 언급 한 것과 동일한 오류가 발생했습니다.
Mo Gauvin

@PaulMatthews, 수정하려면 Uri를 읽는 행을 제거하십시오. myUri = new Uri (RawUrl); 다음과 같이 RawUrl을 마지막 명령문으로 전달하기 만하면됩니다. string param1 = HttpUtility.ParseQueryString (RawUrl) .Get ( "param2");
Mo Gauvin

예, 쿼리 문자열 부분 만 구문 분석한다는 사실은 이름과 설명서에 있습니다. 버그가 아닙니다. 그들이 어떻게 그것을 더 명확하게 만들 수 있는지조차 확실하지 않습니다. 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 리플렉터를 사용하여의 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.