2010-12-08 3 views
11

J'ai besoin de combiner deux uris relatifs, par ex. ../mypath/ et myimage.png pour créer ../mypath/myimage.png. Ils ne sont pas des chemins d'accès aux fichiers sur le disque, donc n'est pas approprié (ce sont des chemins relatifs aux ressources pour une page Web). new Uri lève un ArgumentOutOfRangeException parce que l'uri de base est relatif (pas absolu).Combinaison de deux Uris relatives

Ai-je d'autres options que de rechercher une barre oblique et de combiner les chemins moi-même?

EDIT:

Voici un test qui démontre que Path.Combine ne fonctionnera pas dans le cas où la première URL ne contient pas déjà un slash:

// 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

duplication possible de [Combiner baseUri relative avec chemin relatif] (http: // stackoverflow.com/questions/4925468/combine-relative-baseuri-with-relative-path) –

Répondre

4

Ne pas utiliser le chemin .combinez comme c'est le cas pour le chemin physcial afin qu'il puisse vous confondre avec des barres obliques. Vous pouvez faire votre propre fonction de combiner Uri. Vérifier la barre oblique à la fin et l'ajouter au suivant.

Le constructeur URI peut-il avoir deux arguments?

new Uri(Uri baseUri, string relativeUri) 
+7

Comme je l'ai dit dans la publication en utilisant ce nouveau constructeur URI échoue avec une 'ArgumentOutOfRangeException' parce que le baseUri est relatif. Créer ma propre fonction semble vraiment être ma seule option. –

+1

Je pense que c'est la meilleure façon de le faire. Prenez l'aide de la classe VirtualPathUtility. Il a la fonction de combinaison mais je ne suis pas sûr si cela correspond exactement à vos besoins. Mais il a des fonctions qui pourraient aider à en faire un. par exemple. AppendTrailingSlash et AppendTrailingSlash –

+1

VirtualPathUtility.AppendTrailingSlash plus simple concaténation de chaîne résout cette question. Cependant à la fin j'ai décidé d'exiger et de documenter que la barre oblique finale était exigée pour le chemin de base en premier lieu. –

3

Vous pouvez utiliser le constructeur Uri qui prend une base et une partie par rapport à faire la combinaison - mais notez que le comportement ne peut pas être ce que vous attendez. La classe Uri verra la partie finale de votre base comme un "répertoire" ou un "fichier" (pour le mettre en termes de chemin). S'il voit la fin comme un fichier, cela sera supprimé. Par exemple, si vous combinez http://server/something/ avec resource.png, vous obtiendrez http://server/something/resource.png.

omettent Maintenant, le slash: combiner http://server/something avec resource.png et obtenir http://server/resource.png.

Cela a du sens si vous pensez à partir d'un Uri de base de http://server/something.png et de demander l'URI relatif resource.png: http://server/something.png/resource.png n'est pas ce que vous cherchez.

Si vous savez TOUJOURS qu'ils doivent être ajoutés, vous devez vous assurer que la base se termine par une barre oblique avant la combinaison.

8

Si votre deuxième partie est (comme dans mon cas) vraiment un nom de fichier sans Escaping (et en tant que telle peut contenir les caractères pour une url invalides), voici la solution que j'ai fini avec:

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

Attention, cette solution ne supporte pas un uri complet (avec schéma, hôte, port): elle va lancer une exception avec un uri complet. Merci à Manish Pansiniya pour mentioning System.Web.VirtualPathUtility.

En outre, comme mon nom de fichier était en fait un chemin de fichier partiel (certains noms de dossiers suivis par nom de fichier), plutôt que d'appeler directement System.Uri.EscapeDataString, j'appeler la fonction suivante:

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

(Nécessite l'utilisation de System.Linq pour .Select et fx4 pour la chaîne utilisée.Joint surcharge.)

Questions connexes