88

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?

alex
  • 6,818
  • 9
  • 52
  • 103
Nikolai Samteladze
  • 7,699
  • 6
  • 44
  • 70

16 Answers16

97

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

mLar
  • 2,967
  • 2
  • 22
  • 23
  • 11
    This 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
52
Url.Content("~/")

worked for me!

Athadu
  • 854
  • 7
  • 13
44

You could use VirtualPathRoot property from HttpRequestContext (request.GetRequestContext().VirtualPathRoot)

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Kiran
  • 56,921
  • 15
  • 176
  • 161
  • 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
  • 1
    Hmm..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
  • 3
    Ok, 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
  • 6
    Ok, 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
    new Uri(Request.RequestUri, RequestContext.VirtualPathRoot) – MoonStom Jun 25 '15 at 20:40
  • 2
    Request.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
18

In .NET Core WebAPI (version 3.0 and above):

var requestUrl = $"{Request.Scheme}://{Request.Host.Value}/";


     
Gokulnath
  • 1,166
  • 15
  • 29
16

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));
David Martin
  • 11,764
  • 1
  • 61
  • 74
10

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);
    }

}
Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • And how do you inject HttpRequestMessage? – Richard Szalay Jul 15 '14 at 01:01
  • 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
8

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

Raffaeu
  • 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
5
new Uri(Request.RequestUri, RequestContext.VirtualPathRoot)
MoonStom
  • 2,847
  • 1
  • 26
  • 21
4

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}";
}
Jan Zahradník
  • 2,417
  • 2
  • 33
  • 44
1

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

Mrchief
  • 75,126
  • 20
  • 142
  • 189
1

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", "")
Yasin Patel
  • 5,624
  • 8
  • 31
  • 53
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("~/");
    }
}
yu yang Jian
  • 6,680
  • 7
  • 55
  • 80
0

send a GET to a page and the content replied will be the answer.Base url : http://website/api/

Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116
zeo
  • 11
  • 1
0
  1. Add a reference to System.Web using System.Web;

  2. Get the host or any other component of the url you want string host = HttpContext.Current.Request.Url.Host;

Alon S
  • 107
  • 13
-1

From HttpRequestMessage

request.Headers.Host
Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116
-1

Al WebApi 2, just calling HttpContext.Current.Request.Path;

Fernando Torres
  • 1,070
  • 8
  • 19