如何在Web API控制器中获取基本URL?

89

我知道可以使用Url.Link()获取特定路由的URL,但在Web API控制器中如何获取Web API基本URL?

16个回答

97

11
这是不正确的,只适用于在IIS中将您的站点作为根站点运行的情况。如果您在另一个应用程序中运行应用程序,例如http://localhost:85458/Subfolder/api/ctrl,则会得到错误的答案(它不会包括“/Subfolder”,但实际上应该包括)。 - Arbiter
@Arbiter 获取特定应用程序的基本URL与获取URL的基础不同。所以这个答案并不是错误的,只是根据需要可能会有不同的基本URL。 - Brain2000

52
Url.Content("~/")

对我很有效!


我来这里就是为了这个答案 :) - Marek
2
适用于 .Net Core 2.2 - MiBol

45
您可以使用来自HttpRequestContextrequest.GetRequestContext().VirtualPathRoot)的VirtualPathRoot属性。

12
在这种情况下,Request.GetRequestContext().VirtualPathRoot返回 /。我在使用Owin在Windows服务中托管Web API时自己搭建了本地主机。有没有办法获取基本的URL?谢谢。 - Nikolai Samteladze
1
嗯...这应该返回正确的虚拟路径。我现在自己尝试了一下,它运行得很好。你能分享一下你是如何设置虚拟路径的吗?(例如,我是这样做的:using (WebApp.Start<Program>("http://localhost:9095/Test")),其中VirtualPathRoot返回/Test - Kiran
3
好的,这很有道理。我设置了 http://localhost:5550/ 并且它正确地返回 /。我的意思是如何在这种情况下获取 http://localhost:5550/... - Nikolai Samteladze
6
好的,既然您可以访问HttpRequestMessage(Request.RequestUri),那么您可以获取其请求URI,并找到方案、主机和端口,对吗? - Kiran
14
使用RequestContext.VirtualPathRoot创建新的Uri,基于Request.RequestUri,保留原始含义。 - MoonStom
2
Request.GetRequestContext().VirtualPathRoot在netcore 1.6.1上无法工作,因为HttpRequestContext在那里不存在,是否有任何替代方案? - Shankar S

20

在 .NET Core WebAPI(3.0 及以上版本)中:

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


     

Request 的依赖关系是什么? - Jannick Breunis
请求是ApiController(和普通控制器)的一个属性。因此,在控制器的代码中,不再需要其他依赖。 @JannickBreunis - undefined

16

这是我使用的:

Uri baseUri = new Uri(Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.PathAndQuery, String.Empty));

然后当我将它与另一个相对路径结合使用时,我使用以下内容:

string resourceRelative = "~/images/myImage.jpg";
Uri resourceFullPath = new Uri(baseUri, VirtualPathUtility.ToAbsolute(resourceRelative));

10

我将这个服务注入到我的控制器中。

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

}

你如何注入 HttpRequestMessage? - Richard Szalay
1
@RichardSzalay Autofac已经内置了它, https://github.com/autofac/Autofac/blob/master/Core/Source/Autofac.Integration.WebApi/RegistrationExtensions.cs#L131 但总的来说,您需要设置一个DI容器,然后使用消息处理程序来获取HttpRequestMessage并将其注册在每个请求处理程序中。 - Darrel Miller

8

在Azure上使用自定义域时,Url.Link返回.websites域而不是自定义域,为什么会这样? - JobaDiniz

5
new Uri(Request.RequestUri, RequestContext.VirtualPathRoot)

4
在ASP.NET Core中,ApiControllerRequest属性只是消息。但仍然有一个Context.Request,您可以在其中获取预期的信息。个人建议使用此扩展方法:
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}";
}

1

首先,您可以使用HttpContext.Current.Request.Url.ToString();获取完整的URL,然后使用Replace("user/login", "")替换您的方法URL。

完整代码如下:

string host = HttpContext.Current.Request.Url.ToString().Replace("user/login", "")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接