关于SO已经有类似的问题,答案是:
new Uri(new Uri(base_url),relative_url);
然而,这不是正确答案,因为它会转换字符。考虑你有相对网址,如:
hello%2Fworld.html
这是有效的网址,当您运行上面的代码时,您将获得一个页面hello/world.html
,这在技术上是有效的,但它没用,因为服务器不太可能拥有两个网页的2个页面副本。
在我编写自己的用于组合网址的自定义功能之前,是否有任何现有功能组合网址并且不进行任何转换?
我目前的解决方案基于“发现”,即根据方案完成字符转换。对于ftp协议,保留字符。由于它有点hackery,我也确保我不会对未来改变这种行为感到惊讶。我的代码如下:
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
扩展名更改为您库中的内容。
答案 0 :(得分: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;
}
}