How to generate absolute URLs in ASP.NET Core
Niels Swimberghe - - .NET
Follow me on Twitter, buy me a coffee
URLs are what makes the web the web. In ASP.NET Core Controllers, Razor Pages, and Razor views, there's a Url
property which gives you access to the UrlHelper
. Using the UrlHelper
you can generate URLs to MVC actions, pages, and routes. Take a look at this C# expression:
Url.Action(action: "Home", controller: "Privacy")
The result of this expression will be a URL string pointing to the Privacy
action on the HomeController
: "/Home/Privacy"
.
This is only the absolute path, but that is a valid URL and should work fine. However, sometimes you want to get the absolute URL which includes the scheme, the hostname or domain name, and the port. For this purpose, the methods on the UrlHelper
have overloads to specify the protocol
which is the scheme, and the host
which is the hostname or domain name. Take a look at this C# expression:
Url.Action(action: "Home", controller: "Privacy", values: null, protocol: "https", host: "your-website")
By specifying the protocol and host, the result is now "https://your-website/Home/Privacy"
.
However, if you omit the host
parameter but keep the protocol
parameter, the result will still be an absolute URL, because the host
parameter will default to the host used for the current HTTP request.
Url.Action(action: "Home", controller: "Privacy", values: null, protocol: "https")
The result will be something like "https://localhost:7184/Home/Privacy"
. Whatever the host and port used to make this HTTP request will be used to generate this URL.
When you're handling an HTTP request in ASP.NET Core, you can also access the Scheme
property on the HttpRequest
, so you could pass the scheme as the protocol
parameter to generate the URL with same scheme and host as the current HTTP request.
Url.Action(action: "Privacy", controller: "Home", values: null, protocol: Request.Scheme)
You could also pass in Request.Host
as the host
parameter, but you don't need to as it already uses the host from the current HTTP request when you specify the protocol
without specifying the host
parameter.
What if you don't have access to the UrlHelper
or you need to build a URL in a way that the UrlHelper
doesn't support?
You can also create the absolute base URL for the current HTTP request by grabbing the properties from the HttpRequest
. The following code builds the absolute URL for the absolute path "/your/custom/path":
$"{Request.Scheme}://{Request.Host}{Request.PathBase}/your/custom/path"
The result of this expression looks like "https://localhost:7184/your/custom/path"
.
If you need the full absolute URL including the current absolute path, you could use the following C# expression:
$"{Request.Scheme}://{Request.Host}{Request.PathBase}{Request.Path}"
What if there's no HTTP request?
If there is no HTTP request that you're handling in your code, like when you're doing some background processing using a BackgroundWorker
, you'll need to get the scheme and host some other way. You could store your desired scheme and host into your configuration, or combine them together in a single property and store it into your configuration. Once configured, extract it from configuration and use it to build your absolute URL.
Conclusion #
By default, the UrlHelper
methods will generate absolute paths which isn't the same as a full absolute URL because it doesn't contain the scheme, hostname, and port number. However, the UrlHelper
methods do contain overloads which allow you to generate the full absolute URL.
You can also manually build the absolute URL using the HttpRequest
properties or by storing the desired scheme and hostname from configuration and then extracting it.
In most cases, using an absolute path will be sufficient and it'll save some characters in your HTML, but absolute URLs are sometimes required such as for the technical SEO and social meta tags.