2010-12-08 47 views
11

我需要組合兩個相對的Uris,例如, ../mypath/myimage.png創建../mypath/myimage.png。它們不是磁盤上文件的路徑,因此Path.Combine不合適(它們是網頁資源的相對路徑)。 new Uri將拋出一個ArgumentOutOfRangeException,因爲基本uri是相對的(不是絕對的)。組合兩個相對的Uris

除了檢查尾部斜線,然後自己組合路徑之外,是否還有其他選擇?

編輯:

這裏是證明Path.Combine不會爲的情況下工作時,第一個網址沒有包含尾隨斜線測試用例:

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

[Combine relative baseUri with relative path](http:// stackoverflow。com/questions/4925468/combine-relative-baseuri -with-relative-path) – 2015-04-29 18:19:02

回答

4

不要使用路徑組合,因爲它是物理路徑,所以它可能會混淆你與斜線。你可以讓你自己的Uri功能結合起來。最後檢查斜線並將其附加到下一個。

具有兩個參數的URI構造函數可以幫助嗎?

new Uri(Uri baseUri, string relativeUri) 
+7

正如我在文章中所說的那樣,由於baseUri是相對的,所以新的URI構造函數因`ArgumentOutOfRangeException`失敗。創建我自己的功能似乎是我唯一的選擇。 – 2010-12-08 18:53:26

3

可以使用Uri構造函數,基地和相對部分做組合 - 但要注意的行爲將可能不是你所期望的。 Uri類會將基地的末端部分視爲「目錄」或「文件」(以路徑術語表示)。如果它將結尾看作一個文件,那將被刪除。

例如,結合http://server/something/resource.png會給你http://server/something/resource.png

現在省略斜線:將http://server/somethingresource.png組合並獲得http://server/resource.png

這是有道理的,如果你認爲它是用鹼的http://server/something.png開放的啓動和要求相對URI resource.pnghttp://server/something.png/resource.png是不是你要找的東西。

如果您總是知道它們應該被追加,您需要確保在組合之前以斜槓結尾。

8

如果你的第二個部分是(像我自己的情況)真的沒有任何轉義(並因此可能含有殘疾人一個網址字符)的文件名,這裏是我已經結束了與解決方案:

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

請注意,此解決方案不支持完整的uri(包括方案,主機,端口):它會拋出一個全部uri異常。 感謝Manish Pansiniya爲mentioning System.Web.VirtualPathUtility

此外,作爲我的文件名,其實是部分文件路徑(某些文件夾名稱後面的文件名),而不是直接調用System.Uri.EscapeDataString,我調用下面的函數:

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

(需要使用System.Linq for .Select和fx4作爲所使用的字符串。加入過載。)