I know that I can use Url.Link()
to get URL of a specific route, but how can I get Web API base URL in Web API controller?

- 6,818
- 9
- 52
- 103

- 7,699
- 6
- 44
- 70
16 Answers
In the action method of the request to the url "http://localhost:85458/api/ctrl/"
var baseUrl = Request.RequestUri.GetLeftPart(UriPartial.Authority) ;
this will get you http://localhost:85458

- 2,967
- 2
- 22
- 23
-
11This is incorrect, it only happens to work if you're running your site as the root site in IIS. If you're running your application within another application, i.e. http://localhost:85458/Subfolder/api/ctrl then this would yield the wrong answer (it wouldn't include "/Subfolder" which it should). – Arbiter Jun 14 '17 at 15:09
-
@Arbiter Getting the base URL for a specific application is different than getting the base of a URL. So it's not that this answer is incorrect, just that there might be a different base url depending on the need – Brain2000 Aug 02 '23 at 14:25
You could use VirtualPathRoot
property from HttpRequestContext
(request.GetRequestContext().VirtualPathRoot
)
-
12`Request.GetRequestContext().VirtualPathRoot` returns `/`. I self-host Web API on localhost in Windows service using Owin. Any way to get base URL in this case? Thank you. – Nikolai Samteladze Nov 08 '13 at 19:08
-
1Hmm..this should return the correct virtual path. I tried it myself now and it works fine. Could you share how you are setting the virtual path (for example, I do like this: `using (WebApp.Start
("http://localhost:9095/Test"))` where VirtualPathRoot returns `/Test`) – Kiran Nov 08 '13 at 19:24 -
3Ok, this makes sense. I set `http://localhost:5550/` and it correctly returns `/`. What I meant is how to get `http://localhost:5550/` in this case... – Nikolai Samteladze Nov 08 '13 at 19:29
-
6Ok, since you have access to the HttpRequestMessage(`Request.RequestUri`), you could grab the request uri of it and find the scheme,host and port...right? – Kiran Nov 08 '13 at 19:41
-
14
-
2Request.GetRequestContext().VirtualPathRoot is not working on netcore 1.6.1 as HttpRequestContext doesn't exist there, is there any alternative ? – Shankar S Feb 06 '18 at 09:56
In .NET Core WebAPI (version 3.0 and above):
var requestUrl = $"{Request.Scheme}://{Request.Host.Value}/";

- 1,166
- 15
- 29
This is what I use:
Uri baseUri = new Uri(Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.PathAndQuery, String.Empty));
Then when I combine it with another relative path, I use the following:
string resourceRelative = "~/images/myImage.jpg";
Uri resourceFullPath = new Uri(baseUri, VirtualPathUtility.ToAbsolute(resourceRelative));

- 11,764
- 1
- 61
- 74
I inject this service into my controllers.
public class LinkFactory : ILinkFactory
{
private readonly HttpRequestMessage _requestMessage;
private readonly string _virtualPathRoot;
public LinkFactory(HttpRequestMessage requestMessage)
{
_requestMessage = requestMessage;
var configuration = _requestMessage.Properties[HttpPropertyKeys.HttpConfigurationKey] as HttpConfiguration;
_virtualPathRoot = configuration.VirtualPathRoot;
if (!_virtualPathRoot.EndsWith("/"))
{
_virtualPathRoot += "/";
}
}
public Uri ResolveApplicationUri(Uri relativeUri)
{
return new Uri(new Uri(new Uri(_requestMessage.RequestUri.GetLeftPart(UriPartial.Authority)), _virtualPathRoot), relativeUri);
}
}

- 139,164
- 32
- 194
- 243
-
-
1@RichardSzalay Autofac has it built in, https://github.com/autofac/Autofac/blob/master/Core/Source/Autofac.Integration.WebApi/RegistrationExtensions.cs#L131 but the general idea is you setup a DI container and then use a message handler to grab the HttpRequestMessage and register it in a per-request handler. – Darrel Miller Jul 15 '14 at 02:47
Use the following snippet from the Url helper class
Url.Link("DefaultApi", new { controller = "Person", id = person.Id })
The full article is available here: http://blogs.msdn.com/b/roncain/archive/2012/07/17/using-the-asp-net-web-api-urlhelper.aspx
This is the official way which does not require any helper or workaround. If you look at this approach is like ASP.NET MVC

- 6,694
- 13
- 68
- 110
-
when using a custom domain on Azure, the Url.Link returns the .websites domain instead of the custom domain, why is that? – JobaDiniz Oct 29 '20 at 14:40
In ASP.NET Core ApiController
the Request
property is only the message. But there is still Context.Request
where you can get expected info. Personally I use this extension method:
public static string GetBaseUrl(this HttpRequest request)
{
// SSL offloading
var scheme = request.Host.Host.Contains("localhost") ? request.Scheme : "https";
return $"{scheme}://{request.Host}{request.PathBase}";
}

- 2,417
- 2
- 33
- 44
Not sure if this is a Web API 2 addition, but RequestContext
has a Url
property which is a UrlHelper
: HttpRequestContext Properties. It has Link
and Content
methods. Details here

- 75,126
- 20
- 142
- 189
First you get full URL using
HttpContext.Current.Request.Url.ToString();
then replace your method url using Replace("user/login", "").
Full code will be
string host = HttpContext.Current.Request.Url.ToString().Replace("user/login", "")

- 5,624
- 8
- 31
- 53

- 19
- 1
Base on Athadu's answer, I write an extenesion method, then in the Controller Class you can get root url by this.RootUrl();
public static class ControllerHelper
{
public static string RootUrl(this ApiController controller)
{
return controller.Url.Content("~/");
}
}

- 6,680
- 7
- 55
- 80
send a GET
to a page and the content replied will be the answer.Base url : http://website/api/

- 23,328
- 24
- 73
- 116

- 11
- 1
Add a reference to System.Web
using System.Web;
Get the host or any other component of the url you want
string host = HttpContext.Current.Request.Url.Host;

- 107
- 13