2010-12-08 17 views
11

Ich muss zwei relative Uris, z. ../mypath/ und myimage.png erstellen ../mypath/myimage.png. Sie sind keine Pfade zu Dateien auf der Festplatte, daher ist Path.Combine nicht geeignet (sie sind relative Pfade zu Ressourcen für eine Webseite). new Uri wirft eine ArgumentOutOfRangeException, weil die Basis-URI relativ ist (nicht absolut).Kombinieren zwei relative Uris

Habe ich andere Optionen, als nach einem Schrägstrich zu suchen und dann die Pfade selbst zu kombinieren?

EDIT:

Hier ist ein Testfall, dass Path.Combine nicht für den Fall, Arbeit zeigt, wenn die erste URL nicht bereits einen Schrägstrich enthalten:

// The first case fails with result "../testpath\resource.png" 
[TestCase("../testpath", "resource.png", "../testpath/resource.png")] 
[TestCase("../testpath/", "resource.png", "../testpath/resource.png")] 
public void TestPathCombine(string path, string resourceName, string expectedResult) { 
    string result = Path.Combine(path, resourceName); 
    Assert.AreEqual(expectedResult, result); 
} 
+0

möglich Duplikat [Kombinieren relativ baseUri mit relativem Pfad] (http: // Stackoverflow.com/questions/4925468/kombinieren-relativer-baseuri-mit-relativen-Pfad) –

Antwort

4

nicht Pfad verwenden kombinieren Sie, wie es für den physischen Pfad ist, damit es Sie mit Schrägstrichen verwechseln kann. Sie können Ihre eigene Funktion von Uri kombinieren. Überprüfen Sie den Schrägstrich am Ende und hängen Sie ihn an den nächsten an.

Kann URI-Konstruktor mit zwei Argumenten helfen?

new Uri(Uri baseUri, string relativeUri) 
+7

Wie ich in dem Beitrag mit diesem neuen URI-Konstruktor erwähnt, scheitert mit einer 'ArgumentOutOfRangeException', weil die BaseUri relativ ist. Das Erstellen meiner eigenen Funktion scheint wirklich meine einzige Option zu sein. –

+1

Ich denke, es ist der beste Weg, es zu tun. Nimm Hilfe der VirtualPathUtility-Klasse. Es hat Mähdrescherfunktion, aber ich bin nicht sicher, ob es genau Ihre Anforderung entspricht. Aber es hat Funktionen, die helfen könnten, eins zu machen. z.B. AppendTrailingSlash und AppendTrailingSlash –

+1

VirtualPathUtility.AppendTrailingSlash plus einfache String-Verkettung löst diese Frage. Am Ende habe ich mich jedoch entschieden, zu verlangen und zu dokumentieren, dass der nachfolgende Schrägstrich für den Basispfad an erster Stelle benötigt wurde. –

3

können Sie den Uri Konstruktor verwenden, die eine Basis und einen relativen Teil nimmt die Kombination zu tun - vielleicht nicht, aber beachten Sie, dass das Verhalten sein wird, was Sie erwarten. Die Klasse Uri sieht den Endteil Ihrer Basis entweder als "Verzeichnis" oder als "Datei" (um es in Pfade zu fassen). Wenn es das Ende als Datei sieht, wird es entfernt.

Wenn Sie beispielsweise http://server/something/ mit resource.png kombinieren, erhalten Sie http://server/something/resource.png.

Nun den Schrägstrich weglassen: http://server/something mit resource.png kombinieren und http://server/resource.png erhalten.

Dies ist sinnvoll, wenn Sie denken, dass es mit einer Basis Uri von http://server/something.png beginnt und fragen nach der relativen uri resource.png: http://server/something.png/resource.png ist nicht das, was Sie suchen.

Wenn Sie IMMER wissen, dass sie angehängt werden sollen, müssen Sie sicherstellen, dass die Basis mit einem Schrägstrich endet, bevor Sie kombinieren.

8

Wenn Ihr zweiter Teil (wie in meinem Fall) ist wirklich ein Dateiname ohne Entkommen (und als solche Invaliden Zeichen für eine URL enthalten), hier ist die Lösung, die ich beendet haben sich mit:

VirtualPathUtility.Combine(
    VirtualPathUtility.AppendTrailingSlash(relativeUri), 
    Uri.EscapeDataString(fileName)); 

Beachten Sie, dass diese Lösung eine vollständige uri (mit Schema, Host, Port) nicht unterstützt: Es wird eine Ausnahme mit einer vollständigen uri werfen. Vielen Dank an Manish Pansiniya für mentioning System.Web.VirtualPathUtility.

Zusätzlich ist, wie meine Dateinamen in der Tat einen Teildateipfad (einige Ordnernamen gefolgt von Dateinamen) war, anstatt direkt System.Uri.EscapeDataString nennen, habe ich rufen Sie die folgende Funktion:

/// <summary> 
/// Convert a partial file path to a partial url path. 
/// </summary> 
/// <param name="partialFilePath">The partial file path.</param> 
/// <returns>A partial url path.</returns> 
public static string ConvertPartialFilePathToPartialUrlPath(
    string partialFilePath) 
{ 
    if (partialFilePath == null) 
     return null; 
    return string.Join("/", 
     partialFilePath.Split('/', '\\') 
      .Select(part => Uri.EscapeDataString(part))); 
} 

(Benötigt System.Linq für .Select und fx4 für die verwendete string.Join Überlastung verwenden.)