1

SO上已经有类似的问题,答案是这样的:

new Uri(new Uri(base_url),relative_url);

然而,这不是正确的答案,因为它会转换字符。考虑您有相对网址,例如:

hello%2Fworld.html

这是有效的 url,当你运行上面的代码时,你会得到一个 page hello/world.html,这在技术上是有效的,但它是无用的,因为服务器不太可能同时拥有两个 URL 的页面的 2 个副本。

在我编写自己的用于组合 URL 的自定义函数之前,是否有任何现有的函数可以组合 URL 并且不进行任何转换?


我当前的解决方案基于“发现”,即根据方案完成字符转换。对于 ftp 协议,字符被保留。由于这有点骇人听闻,我还确保将来我不会对这种行为的改变感到惊讶。我的代码如下:

public static class UrlIO
{
    public static string Combine(string baseUrl, string relativeUrl)
    {
        const string ftp = "ftp";

        var scheme = new Uri(baseUrl).Scheme;
        return scheme + new Uri(new Uri(ftp + baseUrl.DeleteStart(scheme)), relativeUrl).AbsoluteUri.DeleteStart(ftp);
    }

    static UrlIO()
    {
        #if DEBUG
        Assert.AreEqual("ftp://foobar.com/hello_world.html", UrlIO.Combine("ftp://foobar.com/", "/hello_world.html"));
        Assert.AreEqual("ftp://foobar.com/hello_world.html", UrlIO.Combine("ftp://foobar.com/xxx", "/hello_world.html"));
        Assert.AreEqual("ftp://foobar.com/xxx/hello_world.html", UrlIO.Combine("ftp://foobar.com/xxx/", "hello_world.html"));
        Assert.AreEqual("ftp://foobar.com/xxx/hello%2Fworld.html", UrlIO.Combine("ftp://foobar.com/xxx/", "hello%2Fworld.html"));
        Assert.AreEqual("http://foobar.com/xxx/hello%2Fworld.html", UrlIO.Combine("http://foobar.com/xxx/index.html", "hello%2Fworld.html"));
        #endif
    }
}

请将DeleteStart扩展方法更改为您图书馆中的内容。

4

1 回答 1

2

您可以为此使用以下扩展方法。在静态类中添加它。

用法,

string fullUrl=relative_url.ConvertToFullUrl();

扩展方法,

public static string ConvertToFullUrl(this string relativeUrl)
{
    if (!Uri.IsWellFormedUriString(relativeUrl, UriKind.Absolute))
    {
        if (!relativeUrl.StartsWith("/"))
        {
            relativeUrl = relativeUrl.Insert(0, "/");
        }
        if (relativeUrl.StartsWith("~/"))
        {
            relativeUrl = relativeUrl.Substring(1);
        }

        return string.Format(
            "{0}://{1}{2}{3}",
            HttpContext.Current.Request.Url.Scheme,
            HttpContext.Current.Request.Url.Host,
            HttpContext.Current.Request.Url.Port == 80 ? "" : ":" + HttpContext.Current.Request.Url.Port.ToString(),
            relativeUrl);
    }
    else
    {
        return relativeUrl;
    }
}
于 2013-04-03T06:39:05.357 回答