91

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?

16 Answers 16

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

Sign up to request clarification or add additional context in comments.

3 Comments

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. localhost:85458/Subfolder/api/ctrl then this would yield the wrong answer (it wouldn't include "/Subfolder" which it should).
@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
Assuming the use of visual studio,
52
Url.Content("~/")

worked for me!

3 Comments

I came here for this anwser :)
Works on .Net Core 2.2
Assuming the use of visual studio, right click on the project name, then select properties. Next, select "Web" on the left hand menu and you will see the project/base url. In more general scenarios use swagger.
45

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

6 Comments

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.
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...
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?
new Uri(Request.RequestUri, RequestContext.VirtualPathRoot)
Request.GetRequestContext().VirtualPathRoot is not working on netcore 1.6.1 as HttpRequestContext doesn't exist there, is there any alternative ?
|
23

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

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


     

3 Comments

From what dependency is Request from?
Request is a property of ApiController (and normal controller). So in code of a controller, no more dependency is needed. @JannickBreunis
This is the best shortest answer
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));

Comments

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

}

2 Comments

And how do you inject HttpRequestMessage?
@RichardSzalay Autofac has it built in, github.com/autofac/Autofac/blob/master/Core/Source/… 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.
7

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

1 Comment

when using a custom domain on Azure, the Url.Link returns the .websites domain instead of the custom domain, why is that?
5
new Uri(Request.RequestUri, RequestContext.VirtualPathRoot)

Comments

5

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

Comments

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

Comments

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", "")

Comments

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("~/");
    }
}

Comments

0

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

Comments

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;

1 Comment

This does not work for .net core 5
-1

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

Comments

-1

From HttpRequestMessage

request.Headers.Host

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.