将相对baseUri与相对路径相结合

时间:2011-02-07 19:17:29

标签: c# asp.net

我正在寻找一种干净的方式来将相对基础Uri与另一条相对路径相结合。我已尝试过以下操作,但Uri(Uri, string)UriBuilder(Uri)需要绝对Uris(抛出InvalidOperationException:相对URI不支持此操作)。

// where Settings.Default.ImagesPath is "~/path/to/images"
// attempt 1
_imagePath = new Uri(Settings.Default.ImagesPath, image);

// attempt 2
UriBuilder uriBuilder = new UriBuilder(Settings.Default.ImagesPath);
uriBuilder.Path += image;
_imagePath = uriBuilder.Uri;

我不想做任何丑陋的字符串操作,以确保基本路径以尾部斜杠等结束。

6 个答案:

答案 0 :(得分:17)

这仍然比我想要的有点麻烦,但它确实有效。

public static class UriExtensions
{
    public static Uri Combine(this Uri relativeBaseUri, Uri relativeUri)
    {
        if (relativeBaseUri == null)
        {
            throw new ArgumentNullException("relativeBaseUri");
        }

        if (relativeUri == null)
        {
            throw new ArgumentNullException("relativeUri");
        }

        string baseUrl = VirtualPathUtility.AppendTrailingSlash(relativeBaseUri.ToString());
        string combinedUrl = VirtualPathUtility.Combine(baseUrl, relativeUri.ToString());

        return new Uri(combinedUrl, UriKind.Relative);
    }
}

以下是一个示例用法:

Uri imageUrl = new Uri("profile.jpg", UriKind.Relative);
Uri baseImageUrl = new Uri("~/path/to/images", UriKind.Relative);
Uri combinedImageUrl = baseImageUrl.Combine(image);

combinedImageUrl是     〜/路径/到/图像/ profile.jpg

答案 1 :(得分:4)

尝试:

UriBuilder builder = new UriBuilder();
Uri baseUri = builder.Uri;
builder.Path = Settings.Default.ImagesRealtivePath;
if (!builder.Path.EndsWith("/"))
    builder.Path += "/";
_imagePath = baseUri.MakeRelativeUri(new Uri(builder.Uri, image));

这将返回字符串“〜/ path / to / images / image.jpg”。

答案 2 :(得分:1)

首先,感谢您对此帖的回复!

我制作了该方法的简化版本,省略了使用Uri类的“复杂性”。该方法仅将字符串作为参数,并且还返回一个字符串。

public static string MakeRelativeUrl(params string[] relativePaths)
{
    var res = "~/";
    foreach (var relativePath in relativePaths)
    {
        string baseUrl = VirtualPathUtility.AppendTrailingSlash(res);
        res = VirtualPathUtility.Combine(baseUrl, relativePath);
    }
    return res;
}

上面的代码可能对其他想要公开提供此功能的方法而不依赖于Uri或VirtualPathUtility但仅依赖于简单字符串的人有用。

当然可以轻松修改以返回Uri - 仍然保留解析字符串参数的好处:

public static Uri MakeRelativeUrl(params string[] relativePaths)
{
    var res = "~/";
    foreach (var relativePath in relativePaths)
    {
        string baseUrl = VirtualPathUtility.AppendTrailingSlash(res);
        res = VirtualPathUtility.Combine(baseUrl, relativePath);
    }
    return new Uri(res, UriKind.Relative);
}

使用上述两个代码示例:

Image.ImageUrl = MakeRelativeUrl("path", "to", "images", "image.jpg").ToString();
// Image.ImageUrl == "~/path/to/images/image.jpg"

答案 3 :(得分:1)

jrummell的一个稍微更通用的版本的答案是接受第一个参数为绝对或相对Uri

    /// <summary>
    /// Combines two <see cref="Uri"/>s.
    /// </summary>
    /// <param name="baseUri">Relative or absolute base uri.</param>
    /// <param name="relativeUri">Uri to be appended.</param>
    public static Uri Combine(this Uri baseUri, Uri relativeUri)
    {
        if (baseUri == null) throw new ArgumentNullException("baseUri");
        if (relativeUri == null) throw new ArgumentNullException("relativeUri");

        string baseUrl = VirtualPathUtility.AppendTrailingSlash(baseUri.ToString());
        string combinedUrl = VirtualPathUtility.Combine(baseUrl, relativeUri.ToString());

        return new Uri(combinedUrl, baseUri.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative);
    }

答案 4 :(得分:-1)

尝试:

UriBuilder uriBuilder = new UriBuilder(Settings.Default.ImagesRealtivePath);
uriBuilder.Path += image;
_imagePath = uriBuilder.Uri;

答案 5 :(得分:-3)

您可以使用Path.Combine(string, string)来实现此目的。如果它是一个相对URL,输出会有点时髦,但它很容易纠正 - 或者你可以简单地忽略这个问题,大多数用法仍然有用。

Path.Combine("~/path/to/images", "image.jpg");
  

输出:〜/ path / to / images \ image.jpg