当您想从业务逻辑层生成 URL 时,您没有使用 ASP.NET Web 窗体的 Page 类/控件的 ResolveUrl(..) 等的灵活性。此外,您可能需要从 ASP.NET MVC 控制器,你不仅错过了 Web 窗体的 ResolveUrl(..) 方法,而且即使 Url.Action 只需要控制器名称和操作,你也无法获取 Url.Action(..)名称,而不是相对 url。
我尝试过使用
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");
返回:http://localhost/Contact
当页面 url 为:http://localhost/Home/About
返回:http://localhost/MyWebApplication/Contact
当页面 url 为:http://localhost/MyWebApplication/Home/About
string absoluteUrl = UrlUtils.MapUrl("~/Contact", UrlUtils.UrlMapOptions.AlwaysSSL);
返回:**https**://localhost/MyWebApplication/Contact
当页面 url 为:http://localhost/MyWebApplication/Home/About
这是我的类库:
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;
}
}