【发布时间】:2010-09-12 16:17:22
【问题描述】:
这可能用一个例子更容易解释。我正在尝试找到一种转换相对 URL 的方法,例如"/Foo.aspx" 或 "~/Foo.aspx" 变成一个完整的 URL,例如http://localhost/Foo.aspx。这样,当我部署到测试或阶段时,站点运行的域不同,我会得到http://test/Foo.aspx 和http://stage/Foo.aspx。
有什么想法吗?
【问题讨论】:
标签: asp.net
这可能用一个例子更容易解释。我正在尝试找到一种转换相对 URL 的方法,例如"/Foo.aspx" 或 "~/Foo.aspx" 变成一个完整的 URL,例如http://localhost/Foo.aspx。这样,当我部署到测试或阶段时,站点运行的域不同,我会得到http://test/Foo.aspx 和http://stage/Foo.aspx。
有什么想法吗?
【问题讨论】:
标签: asp.net
您只需要使用page.request.url 创建一个新的URI,然后获取它的AbsoluteUri:
New System.Uri(Page.Request.Url, "Foo.aspx").AbsoluteUri
【讨论】:
Request.Url 通常不包含已经请求的页面名称吗?为什么OldFoo.aspx与Foo.aspx不冲突? (即:new Uri() 是在将基本 URI 与相关部分组合之前剥离它吗?)
在ASP.NET MVC中,可以使用Url.Content(relativePath)转换成绝对Url
【讨论】:
从其他答案修改为与 localhost 和其他端口一起工作......我正在使用 ex。电子邮件链接。您可以从应用程序的任何部分调用,不仅在页面或用户控件中,我将其放在 Global 中,不需要将 HttpContext.Current.Request 作为参数传递
/// <summary>
/// Return full URL from virtual relative path like ~/dir/subir/file.html
/// usefull in ex. external links
/// </summary>
/// <param name="rootVirtualPath"></param>
/// <returns></returns>
public static string GetAbsoluteFullURLFromRootVirtualPath(string rootVirtualPath)
{
return string.Format("http{0}://{1}{2}{3}",
(HttpContext.Current.Request.IsSecureConnection) ? "s" : ""
, HttpContext.Current.Request.Url.Host
, (HttpContext.Current.Request.Url.IsDefaultPort) ? "" : ":" + HttpContext.Current.Request.Url.Port
, VirtualPathUtility.ToAbsolute(rootVirtualPath)
);
}
【讨论】:
这是一种方法。这不关心字符串是相对的还是绝对的,但您必须提供一个 baseUri 供它使用。
/// <summary>
/// This function turns arbitrary strings containing a
/// URI into an appropriate absolute URI.
/// </summary>
/// <param name="input">A relative or absolute URI (as a string)</param>
/// <param name="baseUri">The base URI to use if the input parameter is relative.</param>
/// <returns>An absolute URI</returns>
public static Uri MakeFullUri(string input, Uri baseUri)
{
var tmp = new Uri(input, UriKind.RelativeOrAbsolute);
//if it's absolute, return that
if (tmp.IsAbsoluteUri)
{
return tmp;
}
// build relative on top of the base one instead
return new Uri(baseUri, tmp);
}
在 ASP.NET 上下文中,您可以这样做:
Uri baseUri = new Uri("http://yahoo.com/folder");
Uri newUri = MakeFullUri("/some/path?abcd=123", baseUri);
//
//newUri will contain http://yahoo.com/some/path?abcd=123
//
Uri newUri2 = MakeFullUri("some/path?abcd=123", baseUri);
//
//newUri2 will contain http://yahoo.com/folder/some/path?abcd=123
//
Uri newUri3 = MakeFullUri("http://google.com", baseUri);
//
//newUri3 will contain http://google.com, and baseUri is not used at all.
//
【讨论】:
古老的问题,但我想我会回答它,因为许多答案都不完整。
public static string ResolveFullUrl(this System.Web.UI.Page page, string relativeUrl)
{
if (string.IsNullOrEmpty(relativeUrl))
return relativeUrl;
if (relativeUrl.StartsWith("/"))
relativeUrl = relativeUrl.Insert(0, "~");
if (!relativeUrl.StartsWith("~/"))
relativeUrl = relativeUrl.Insert(0, "~/");
return $"{page.Request.Url.Scheme}{Uri.SchemeDelimiter}{page.Request.Url.Authority}{VirtualPathUtility.ToAbsolute(relativeUrl)}";
}
这可以作为页面外的扩展,就像 Web 表单的 ResolveUrl 和 ResolveClientUrl 一样。如果您想或需要在非网络表单环境中使用它,请随意将其转换为 HttpResponse 扩展。它可以正确处理标准和非标准端口上的 http 和 https,以及是否存在用户名/密码组件。它也不使用任何硬编码字符串(即://)。
【讨论】:
玩玩这个(修改from here)
public string ConvertRelativeUrlToAbsoluteUrl(string relativeUrl) {
return string.Format("http{0}://{1}{2}",
(Request.IsSecureConnection) ? "s" : "",
Request.Url.Host,
Page.ResolveUrl(relativeUrl)
);
}
【讨论】:
Page.ResolveUrl 只能在 Page 的上下文中调用。我将代码调整为:return string.Format("{0}://{1}{2}{3}", (Request.IsSecureConnection) ? "https" : "http", Request.Url.Host, (Request.Url.Port == 80) ? "" : ":"+Request.Url.Port.ToString(), VirtualPathUtility.ToAbsolute(relativeUrl)
在 ASP.NET MVC 中,您可以使用采用 protocol 或 host 参数的 HtmlHelper 或 UrlHelper 的重载。当这些参数中的任何一个不为空时,帮助程序生成一个绝对 URL。这是我正在使用的扩展方法:
public static MvcHtmlString ActionLinkAbsolute<TViewModel>(
this HtmlHelper<TViewModel> html,
string linkText,
string actionName,
string controllerName,
object routeValues = null,
object htmlAttributes = null)
{
var request = html.ViewContext.HttpContext.Request;
var url = new UriBuilder(request.Url);
return html.ActionLink(linkText, actionName, controllerName, url.Scheme, url.Host, null, routeValues, htmlAttributes);
}
并从 Razor 视图中使用它,例如:
@Html.ActionLinkAbsolute("Click here", "Action", "Controller", new { id = Model.Id })
【讨论】:
我想我会分享我在 ASP.NET MVC 中使用 Uri 类和一些扩展魔法的方法。
public static class UrlHelperExtensions
{
public static string AbsolutePath(this UrlHelper urlHelper,
string relativePath)
{
return new Uri(urlHelper.RequestContext.HttpContext.Request.Url,
relativePath).ToString();
}
}
然后您可以使用以下命令输出绝对路径:
// gives absolute path, e.g. https://example.com/customers
Url.AbsolutePath(Url.Action("Index", "Customers"));
嵌套的方法调用看起来有点难看,所以我更喜欢用常见的操作方法进一步扩展UrlHelper,这样我就可以做到:
// gives absolute path, e.g. https://example.com/customers
Url.AbsoluteAction("Index", "Customers");
或
Url.AbsoluteAction("Details", "Customers", new{id = 123});
完整的扩展类如下:
public static class UrlHelperExtensions
{
public static string AbsolutePath(this UrlHelper urlHelper,
string relativePath)
{
return new Uri(urlHelper.RequestContext.HttpContext.Request.Url,
relativePath).ToString();
}
public static string AbsoluteAction(this UrlHelper urlHelper,
string actionName,
string controllerName)
{
return AbsolutePath(urlHelper,
urlHelper.Action(actionName, controllerName));
}
public static string AbsoluteAction(this UrlHelper urlHelper,
string actionName,
string controllerName,
object routeValues)
{
return AbsolutePath(urlHelper,
urlHelper.Action(actionName,
controllerName, routeValues));
}
}
【讨论】:
这个已经被打死了,但我想我会发布我自己的解决方案,我认为它比许多其他答案更干净。
public static string AbsoluteAction(this UrlHelper url, string actionName, string controllerName, object routeValues)
{
return url.Action(actionName, controllerName, routeValues, url.RequestContext.HttpContext.Request.Url.Scheme);
}
public static string AbsoluteContent(this UrlHelper url, string path)
{
Uri uri = new Uri(path, UriKind.RelativeOrAbsolute);
//If the URI is not already absolute, rebuild it based on the current request.
if (!uri.IsAbsoluteUri)
{
Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
UriBuilder builder = new UriBuilder(requestUrl.Scheme, requestUrl.Host, requestUrl.Port);
builder.Path = VirtualPathUtility.ToAbsolute(path);
uri = builder.Uri;
}
return uri.ToString();
}
【讨论】:
code return url.Action(actionName, controllerName, routeValues, url.RequestContext.HttpContext.Request.Url.Scheme); code
简单地说:
url = new Uri(baseUri, url);
【讨论】:
这是我为进行转换而创建的辅助函数。
//"~/SomeFolder/SomePage.aspx"
public static string GetFullURL(string relativePath)
{
string sRelative=Page.ResolveUrl(relativePath);
string sAbsolute=Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery,sRelative);
return sAbsolute;
}
【讨论】:
这是我的辅助函数
public string GetFullUrl(string relativeUrl) {
string root = Request.Url.GetLeftPart(UriPartial.Authority);
return root + Page.ResolveUrl("~/" + relativeUrl) ;
}
【讨论】:
使用 .NET Uri 类来组合您的相对路径和主机名。
http://msdn.microsoft.com/en-us/library/system.uri.aspx
【讨论】:
System.Uri(System.Uri(base_uri), relative_uri).AbsoluteUri