2012-10-23 8 views
5

Sto scrivendo un'applicazione C# che deve fare callout a una webapp. Sto cercando di utilizzare System.Uri per combinare due URL: un URL di base e il percorso relativo al servizio specifico (o molti) dell'applicazione web di cui ho bisogno. Ho un membro della classe chiamato webappBackendURL che voglio definire in un posto, con tutte le chiamate costruite da esso (webappBackendURL non è definito il più vicino come illustrano i miei esempi).Come combinare gli URL con le parti della stringa di query preservate?

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

questo funziona, tuttavia, se webappBackendURL contiene una stringa di query, non è conservato.

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) 

C'è un modo migliore di combinare gli URL? La libreria .NET è estesa, quindi penso che avrei potuto semplicemente trascurare un modo integrato per gestirlo. Idealmente, vorrei essere in grado di coniugare gli URL come questo:

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 

risposta

2

Si potrebbe fare qualcosa di simile:

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

Anche se avrei probabilmente creare un metodo che prende due URI e fa l'elaborazione lì in modo che sembrava un po 'più pulito.

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

Ho colpito un 'UriFormatException' quando ho cercato di costruire un' Uri' dal mio percorso semplice, quindi non penso di poter usare in modo affidabile 'MergerUri'. Potrei provare a racchiudere il tuo suggerimento iniziale in un metodo. – jimp

+0

Mi dispiace per non averlo provato prima. Quello aggiornato funzionerà ma è simile a quello che hai deciso. – jfin3204

1

Prova 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 si è spostato tra versioni diverse di .NET. Dovrai determinare quale riferimento all'assemblaggio è corretto per il tuo progetto.

+0

Sembra interessante. Controllerò, grazie. – jimp

+0

Ho usato solo un parametro perché questo corrispondeva maggiormente a quello che stavi chiedendo, ma puoi avere modelli con più di uno (/ {x}/{y}/foo). Ovviamente ci sarebbe una voce nel NameValueCollection per ciascuno dei segnaposto. –

0

Utilizzando idee e pezzi dalle risposte ricevute, ho scritto un metodo wrapper che ha ottenuto esattamente quello che stavo cercando. Speravo che le classi .NET di base potessero gestirlo, ma sembra che non possano.

Questo metodo richiede un URL completo (http://example.com?path?query=string) e combina un URL relativo (stringa) nel formato relative/path?query=string&with=arguemnts.

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 

Grazie a tutti quelli che hanno contribuito! Ho upvoted tutte le vostre risposte.

Problemi correlati