2012-10-23 2 views
5

나는 webapp에 콜 아웃해야하는 C# 응용 프로그램을 작성 중입니다. System.Uri을 사용하여 두 개의 URL을 결합하려고합니다. 기본 URL과 필요한 특정 웹 서비스의 상대 경로 (또는 많은 경로). 나는 한 곳에서 정의하고자하는 webappBackendURL이라는 클래스 멤버를 가지고 있으며, 모든 빌드는 그곳에서부터 호출됩니다 (webappBackendURL은 나의 예제처럼 자세히 정의되지 않았습니다).URL을 보존 된 쿼리 문자열 부분과 결합하는 방법은 무엇입니까?

System.Uri webappBackendURL = new System.Uri("http://example.com/"); 
System.Uri rpcURL   = new System.Uri(webappBackendURL,"rpc/import"); 
// Result: http://example.com/rpc/import 

그러나이 경우 webappBackendURL에 쿼리 문자열이 포함되어 있으면 작동하지 않습니다.

System.Uri webappBackendURL = new System.Uri("http://example.com/?authtoken=0x0x0"); 
System.Uri rpcURL   = new System.Uri(webappBackendURL,"rpc/import"); 
// Result: http://example.com/rpc/import <-- (query string lost) 

URL을 결합하는 더 좋은 방법이 있습니까? .NET 라이브러리는 광범위하므로이 문제를 처리 할 수있는 기본 방법을 간과했을 수도 있습니다.

System.Uri webappBackendURL = new System.Uri("http://example.com/?authtoken=0x0x0"); 
System.Uri rpcURL   = new System.Uri(webappBackendURL,"rpc/import?method=overwrite&runhooks=true"); 
// Result: http://example.com/rpc/import?authtoken=0x0x0&method=overwrite&runhooks=true 

답변

2

당신은 같은 것을 할 수있는 : 이상적으로,이 같은 URL을 결합 할 수 있도록하고 싶습니다 아마이 URI를 취하는 방법을 만들 것입니다하지만

System.Uri webappBackendURL = 
    new System.Uri("http://example.com/?authtoken=0x0x0"); 
System.Uri rpcURL = new System.Uri(webappBackendURL, 
    "rpc/import?ethod=overwrite&runhooks=true" 
    + webappBackendURL.Query.Replace("?", "&")); 
1
System.Uri webappBackendURL = new System.Uri("http://example.com/?authtoken=0x0x0"); 
System.Uri rpcURL   = new System.Uri(webappBackendURL,string.Format("rpc/import?{0}method=overwrite&runhooks=true", string.IsNullOrWhiteSpace(webappBackendURL.Query) ? "":webappBackendURL.Query + "&")); 

및 그곳에서 처리를하므로 좀 더 깔끔하게 보입니다.

public static Uri MergerUri(Uri uri1, Uri uri2) 
    { 
     if (!string.IsNullOrWhiteSpace(uri1.Query)) 
     { 
      string[] split = uri2.ToString().Split('?'); 

      return new Uri(uri1, split[0] + uri1.Query + "&" + split[1]); 
     } 
     else return new Uri(uri1, uri2.ToString()); 
    } 
+0

간단한 경로에서'Uri'을 만들려고 할 때'UriFormatException'을 쳤기 때문에'MergerUri'를 신뢰할 수 있다고 생각하지 않습니다. 나는 당신의 초기 제안을 방법으로 포장하려고 노력할지도 모른다. – jimp

+0

죄송합니다. 먼저 테스트하지 않았습니다. 업데이트 된 버전이 작동하지만 결정한 내용과 유사합니다. – jfin3204

1

UriTemplate을 시도해보십시오

Uri baseUrl = new Uri("http://www.example.com"); 
UriTemplate template = new UriTemplate("/{path}/?authtoken=0x0x0"); 
Uri boundUri = template.BindByName(
    baseUrl, 
    new NameValueCollection {{"path", "rpc/import"}}); 

System.UriTemplate

는 .NET의 다른 버전 사이에 주위를 이동했습니다. 프로젝트에 맞는 어셈블리 참조를 결정해야합니다.

+0

재미있을 것 같습니다. 내가 확인해 볼께. 고마워. – jimp

+0

내가 요구 한 것과 가장 일치하는 매개 변수 하나만 사용했으나 하나 이상의 템플릿 (/ {x}/{y}/foo)을 가질 수 있습니다. 분명히 각 자리 표시 자에 대한 NameValueCollection에 하나의 항목이 있습니다. –

0

받은 답안의 아이디어와 조각을 사용하여 필자는 내가 찾고있는 것을 정확히 달성 한 래퍼 메서드를 작성했습니다. 핵심 .NET 클래스가이 문제를 처리 할 수 ​​있기를 기대했지만 불가능한 것처럼 보였습니다.

이 메서드는 전체 URL (http://example.com?path?query=string)을 가져오고 relative/path?query=string&with=arguemnts의 형식으로 상대 URL (문자열)을 결합합니다.

private static System.Uri ExtendURL(System.Uri baseURL, string relURL) 
{ 
    string[] parts = relURL.Split("?".ToCharArray(), 2); 
    if (parts.Length < 1) 
    { 
     return null; 
    } 
    else if (parts.Length == 1) 
    { 
     // No query string included with the relative URL: 
     return new System.Uri(baseURL, 
           parts[0] + baseURL.Query); 
    } 
    else 
    { 
     // Query string included with the relative URL: 
     return new System.Uri(baseURL, 
           parts[0] + (String.IsNullOrWhiteSpace(baseURL.Query) ? "?" : baseURL.Query + "&") + parts[1]); 
    } 
} 

ExtendURL(new System.Uri("http://example.com/?authtoken=0x0x0"),"rpc/import?method=overwrite&runhooks=true"); 
// Result: http://example.com/rpc/import?authtoken=0x0x0&method=overwrite&runhooks=true 

기여하신 모든 분들께 감사드립니다! 나는 당신의 대답 모두를지지했다.

관련 문제