Get Absolute URL from Relative Path (refactoring method)

I am really surprised that there is no native .NET method to get an absolute URL from a relative URL. I know this has been discussed many times, but have never come across a satisfactory method that does this well. Can you help fine tune the method below?

I think that all I need is an automatic protocol selection instead of hard coding it (http / https). Anything else I am missing (reservations, performance, etc.)?

public static string GetAbsoluteUrl(string url) { //VALIDATE INPUT FOR ALREADY ABSOLUTE URL if (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { return url; } //GET PAGE REFERENCE FOR CONTEXT PROCESSING Page page = HttpContext.Current.Handler as Page; //RESOLVE PATH FOR APPLICATION BEFORE PROCESSING if (url.StartsWith("~/")) { url = page.ResolveUrl(url); } //BUILD AND RETURN ABSOLUTE URL return "http://" + page.Request.ServerVariables["SERVER_NAME"] + "/" + url.TrimStart('/'); } 
+48
Sep 09 '10 at 22:36
source share
11 answers

It has always been my approach to this little trouble. Note that using VirtualPathUtility.ToAbsolute (relativeUrl) allows you to declare a method as an extension in a static class.

 /// <summary> /// Converts the provided app-relative path into an absolute Url containing the /// full host name /// </summary> /// <param name="relativeUrl">App-Relative path</param> /// <returns>Provided relativeUrl parameter as fully qualified Url</returns> /// <example>~/path/to/foo to http://www.web.com/path/to/foo</example> public static string ToAbsoluteUrl(this string relativeUrl) { if (string.IsNullOrEmpty(relativeUrl)) return relativeUrl; if (HttpContext.Current == null) return relativeUrl; if (relativeUrl.StartsWith("/")) relativeUrl = relativeUrl.Insert(0, "~"); if (!relativeUrl.StartsWith("~/")) relativeUrl = relativeUrl.Insert(0, "~/"); var url = HttpContext.Current.Request.Url; var port = url.Port != 80 ? (":" + url.Port) : String.Empty; return String.Format("{0}://{1}{2}{3}", url.Scheme, url.Host, port, VirtualPathUtility.ToAbsolute(relativeUrl)); } 
+82
Sep 10 '10 at 5:32
source share
 new System.Uri(Page.Request.Url, "/myRelativeUrl.aspx").AbsoluteUri 
+57
Jan 28 '13 at 10:04 on
source share

This works for me ...

 new System.Uri(Page.Request.Url, ResolveClientUrl("~/mypage.aspx")).AbsoluteUri 
+8
Mar 13 '13 at 17:37
source share

With ASP.NET, you need to consider a breakpoint for a “relative URL” - this is relative to a page request, a user control, or if it is “relative” simply by virtue of using “~ /”,

Uri Class contains an easy way to convert a relative URL to an absolute URL (given the absolute address as a reference point for the relative URL):

 var uri = new Uri(absoluteUrl, relativeUrl); 

If relativeUrl is actually an absolute URL, then absoluteUrl ignored.

All that remains is the question of what is the reference point and whether the URLs are "~ /" (the Uri constructor does not translate them).

+3
Sep 10 2018-10-10T00
source share

Here is my own version, which handles many checks and relative movement from options to the user's current location. Feel free to refactor here :)

 /// <summary> /// Converts the provided app-relative path into an absolute Url containing /// the full host name /// </summary> /// <param name="relativeUrl">App-Relative path</param> /// <returns>Provided relativeUrl parameter as fully qualified Url</returns> /// <example>~/path/to/foo to http://www.web.com/path/to/foo</example> public static string GetAbsoluteUrl(string relativeUrl) { //VALIDATE INPUT if (String.IsNullOrEmpty(relativeUrl)) return String.Empty; //VALIDATE INPUT FOR ALREADY ABSOLUTE URL if (relativeUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || relativeUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) return relativeUrl; //VALIDATE CONTEXT if (HttpContext.Current == null) return relativeUrl; //GET CONTEXT OF CURRENT USER HttpContext context = HttpContext.Current; //FIX ROOT PATH TO APP ROOT PATH if (relativeUrl.StartsWith("/")) relativeUrl = relativeUrl.Insert(0, "~"); //GET RELATIVE PATH Page page = context.Handler as Page; if (page != null) { //USE PAGE IN CASE RELATIVE TO USER CURRENT LOCATION IS NEEDED relativeUrl = page.ResolveUrl(relativeUrl); } else //OTHERWISE ASSUME WE WANT ROOT PATH { //PREPARE TO USE IN VIRTUAL PATH UTILITY if (!relativeUrl.StartsWith("~/")) relativeUrl = relativeUrl.Insert(0, "~/"); relativeUrl = VirtualPathUtility.ToAbsolute(relativeUrl); } var url = context.Request.Url; var port = url.Port != 80 ? (":" + url.Port) : String.Empty; //BUILD AND RETURN ABSOLUTE URL return String.Format("{0}://{1}{2}{3}", url.Scheme, url.Host, port, relativeUrl); } 
+3
May 31 '11 at
source share

Still nothing good comes out using native material. Here is what I ended up with:

 public static string GetAbsoluteUrl(string url) { //VALIDATE INPUT if (String.IsNullOrEmpty(url)) { return String.Empty; } //VALIDATE INPUT FOR ALREADY ABSOLUTE URL if (url.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { return url; } //GET CONTEXT OF CURRENT USER HttpContext context = HttpContext.Current; //RESOLVE PATH FOR APPLICATION BEFORE PROCESSING if (url.StartsWith("~/")) { url = (context.Handler as Page).ResolveUrl(url); } //BUILD AND RETURN ABSOLUTE URL string port = (context.Request.Url.Port != 80 && context.Request.Url.Port != 443) ? ":" + context.Request.Url.Port : String.Empty; return context.Request.Url.Scheme + Uri.SchemeDelimiter + context.Request.Url.Host + port + "/" + url.TrimStart('/'); } 
+1
Sep 10 '10 at 4:14
source share

If you are in the context of an MVC Controller or View, you can use UrlHelper, which should be accessible through Url

 Url.Content("~/content/images/myimage.jpg") 

which will be fully expanded to /virtual_directoryname/content/images/myimage.jpg

This can be used in the controller or in the .cshtml file.

Yes, it’s a little strange that it is called Content , but it should be used to get the absolute path to the resource, so it makes sense

+1
Sep 13 '13 at 2:50
source share

check the following code to get the absolute url:

 Page.Request.Url.AbsoluteUri 

I hope to be of service.

0
Sep 10 2018-10-10T00:
source share

This works fine too:

 HttpContext.Current.Server.MapPath(relativePath) 

If the relative path is something like "~ / foo / file.jpg"

0
Jun 12 '13 at 14:02
source share

If you want to generate a URL from the level of your business logic, you do not have the flexibility to use the ASP.NET Web Form / Control ResolveUrl (..) page class, etc. In addition, you may need to generate the URL from the ASP.NET MVC controller too, where you not only skip the Web Form ResolveUrl (..) method, but also cannot get Url.Action (..), although Url.Action accepts only the controller name and action name, not the relative URL.

I tried to use

var uri = new Uri (absoluteUrl, relativeUrl)

but there is a problem. If the web application is located in the IIS virtual directory, where the application URL looks like this: http://localhost/MyWebApplication1/ and the relative URL is "/ myPage", then the relative URL is resolved as " http://localhost/MyPage ", which is another problem.

Therefore, to overcome such problems, I wrote the UrlUtils class, which can work from the class library. Thus, it does not depend on the page class, but depends on ASP.NET MVC . So, if you do not mind adding a link to the MVC dll to your class library project, then my class will work smoothly. I tested in an IIS virtual directory script where the web application URL looks like this: http://localhost/MyWebApplication/MyPage . I realized that sometimes we need to make sure that the Absolute URL is an SSL URL or not an SSL url. So, I wrote my class library that supports this option. I have limited this class library so that the relative URL can be an absolute URL or a relative URL that starts with '~ /'.

Using this library, I can call

 string absoluteUrl = UrlUtils.MapUrl("~/Contact"); 

Returns: http://localhost/Contact when the page URL: http://localhost/Home/About

Returns: http://localhost/MyWebApplication/Contact when the page URL: http://localhost/MyWebApplication/Home/About

  string absoluteUrl = UrlUtils.MapUrl("~/Contact", UrlUtils.UrlMapOptions.AlwaysSSL); 

Returns: **https**://localhost/MyWebApplication/Contact when the page URL: http://localhost/MyWebApplication/Home/About

Here is my class library:

  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; } } 
0
Mar 29 '14 at 0:45
source share

The final version, which addresses all previous complaints (ports, logical url, relative url, existing absolute url ... etc.). Considering the current handler is the page:

 public static string ConvertToAbsoluteUrl(string url) { if (!IsAbsoluteUrl(url)) { if (HttpContext.Current != null && HttpContext.Current.Request != null && HttpContext.Current.Handler is System.Web.UI.Page) { var originalUrl = HttpContext.Current.Request.Url; return string.Format("{0}://{1}{2}{3}", originalUrl.Scheme, originalUrl.Host, !originalUrl.IsDefaultPort ? (":" + originalUrl.Port) : string.Empty, ((System.Web.UI.Page)HttpContext.Current.Handler).ResolveUrl(url)); } throw new Exception("Invalid context!"); } else return url; } private static bool IsAbsoluteUrl(string url) { Uri result; return Uri.TryCreate(url, UriKind.Absolute, out result); } 
0
Aug 04 '17 at 21:46 on
source share



All Articles