当您想要从业务逻辑层生成URL时,您没有使用ASP.NET Web Form的Page类/Control的ResolveUrl(..)等灵活性。此外,您可能还需要从ASP.NET MVC控制器生成URL,在那里您不仅错过了Web表单的ResolveUrl(..)方法,而且即使Url.Action只需要控制器名称和操作名称而不是相对URL,但您也无法获得Url.Action(..)。
我尝试使用“var uri = new Uri(absoluteUrl, relativeUrl)”方法,但也存在问题。如果Web应用程序托管在IIS虚拟目录中,其中应用程序的URL如下:“http://localhost/MyWebApplication1/”,而相对URL为“/myPage”,则相对URL将解析为“http://localhost/MyPage”,这是另一个问题。
因此,为了克服这些问题,我编写了一个UrlUtils类,可以从一个类库中工作。所以,它不依赖于Page类,但是依赖于
ASP.NET MVC。如果您不介意将MVC dll引用到您的类库项目中,那么我的类将能够顺利工作。我已经在IIS虚拟目录场景中进行了测试,其中Web应用程序url如下:
http://localhost/MyWebApplication/MyPage
。我意识到,有时我们需要确保绝对url是SSL url或非SSL url。因此,我编写了支持此选项的类库。我限制了这个类库,使得相对url可以是绝对url或以“~/”开头的相对url。
使用这个库,我可以调用
string absoluteUrl = UrlUtils.MapUrl("~/Contact")
当页面url为
http://localhost/Home/About
时,返回:
http://localhost/Contact
当页面url为
http://localhost/MyWebApplication/Home/About
时,返回:
http://localhost/MyWebApplication/Contact
string absoluteUrl = UrlUtils.MapUrl("~/Contact", UrlUtils.UrlMapOptions.AlwaysSSL)
返回结果:
当页面url为:http://localhost/MyWebApplication/Home/About
时,返回:**https**://localhost/MyWebApplication/Contact
这是我的类库:
public class UrlUtils
{
public enum UrlMapOptions
{
AlwaysNonSSL,
AlwaysSSL,
BasedOnCurrentScheme
}
public static string MapUrl(string relativeUrl, UrlMapOptions option = UrlMapOptions.BasedOnCurrentScheme)
{
if (relativeUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
relativeUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
return relativeUrl;
if (!relativeUrl.StartsWith("~/"))
throw new Exception("The relative url must start with ~/");
UrlHelper theHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
string theAbsoluteUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) +
theHelper.Content(relativeUrl);
switch (option)
{
case UrlMapOptions.AlwaysNonSSL:
{
return theAbsoluteUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
? string.Format("http://{0}", theAbsoluteUrl.Remove(0, 8))
: theAbsoluteUrl;
}
case UrlMapOptions.AlwaysSSL:
{
return theAbsoluteUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
? theAbsoluteUrl
: string.Format("https://{0}", theAbsoluteUrl.Remove(0, 7));
}
}
return theAbsoluteUrl;
}
}