如何在ASP.NET Core中获取网站的基本URL?


75

假设我的网站托管在www.example.commywebsite文件夹中,并且我访问https://www.example.com/mywebsite/home/about

如何在MVC控制器中获取基本网址部分?我要寻找的部分是https://www.example.com/mywebsite

由于我们无权访问ASP.NET Core中的Request.Url,因此此处列出的示例不起作用


@VSO,如果您查看由OP链接的答案,您将看到核心的更新版本,您应该能够将其转换为服务,以便在请求范围内可以在应用程序中的任何位置访问该请求。stackoverflow.com/a/12144292/5233410在此问题中提供的答案是正确的。你有什么不明白?
恩科西(Nkosi),

Answers:


119

您仍然应该能够拼凑所需的内容。如果您的控制器继承自,则您可以访问请求对象Controller

如果您使用的是VS2017,请启动一个新的ASPNet Core MVC应用并将Homecontroller替换为:

public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    public IActionResult About()
    {
        ViewData["Message"] = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}";

        return View();
    }

    public IActionResult Contact()
    {
        ViewData["Message"] = "Your contact page.";

        return View();
    }

    public IActionResult Error()
    {
        return View();
    }
}

我只是在“ About”方法中加入了一些您可能感兴趣的内容,但是您应该浏览其余的请求类,以便了解还有哪些可用的东西。

正如@Tseng指出的那样,在IIS或Azure App Service后面运行Kestrel时可能会出现问题,但是如果使用IISIntegration包或AzureAppServices包(通过安装Nuget包并将其在Program.cs中添加到WebHostBuilder中),它将应该将这些标头转发给您。在Azure中,这对我来说非常有用,因为有时我必须根据他们命中的主机名来做出决定。IIS / Azure程序包还转发了我记录的原始远程IP地址。


3
那应该是Request.Scheme +“://” + Request.Host + Request.PathBase
Tratcher 17-4-21的

3
我将答案更新为使用PathBase而不是Path。感谢Tratcher指出这一点。
NPNelson

1
我想指出这是多么可怕的想法。用户可以更改“ Url.Request”。请勿在用户信息附近使用此功能。想象一个精心设计的“忘记密码”请求。
johnrom '19

如果我附加.Value.ToString()$“ {this.Request.Scheme}:// {{this.Request.Host.Value.ToString()} {this.Request.PathBase.Value.ToString()}”可以工作;
hubert17 '19

考虑一下,我认为实际上很容易在以后存储和使用此值,而不必知道它最初来自(可能是恶意的)用户输入。我实施了白名单来减轻这种情况。或者,使用该基本URL的客户端也可能向某种服务器发出挑战。
jmathew

44

如果您需要在应用程序中的任何位置使用此工具,则应该构建一个中间件。定义静态类和扩展方法,以将中间件添加到服务管道中,如下所示。

public class MyHttpContext
{
    private static IHttpContextAccessor m_httpContextAccessor;

    public static HttpContext Current => m_httpContextAccessor.HttpContext;

    public static string AppBaseUrl => $"{Current.Request.Scheme}://{Current.Request.Host}{Current.Request.PathBase}";

    internal static void Configure(IHttpContextAccessor contextAccessor)
    {
        m_httpContextAccessor = contextAccessor;
    }
}

public static class HttpContextExtensions
{
    public static void AddHttpContextAccessor(this IServiceCollection services)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }

    public static IApplicationBuilder UseHttpContext(this IApplicationBuilder app)
    {
        MyHttpContext.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());
        return app;
    }
}

在这种情况下公开HttpContext可能有点多余,但是我发现它非常有用。

然后,您可以将其添加到位于Startup.cs中的Configfure方法中的管道中。

app.UseHttpContext()

从那里开始,很容易在代码中的任何地方使用它。

var appBaseUrl = MyHttpContext.AppBaseUrl;

5
如果您从控制器调用MyHttpContext.AppBaseUrl,这似乎起作用。我需要在启动时紧靠app.UseHttpSettings()之后的基本URL。似乎HttpContext在其中为null。有什么想法吗?谢谢

1
确保在ConfigureServices方法中调用services.AddHttpContextAccessor()。
罗布

3
谢谢。还是一样。我在某处读到,因为.NET Core的托管方式,直到完全启动它才具有服务器信息。我试图从StartUp中获取它。

@Whoever您如何解决此问题?我只被困在那里。
Sruthi Varghese

2
@SruthiVarghese我认为您无法从启动中解析主机URL。我的理解是.NET Core都是控制台应用程序,您的启动决定了它的托管方式。因此,相同的代码可以与控制台,iisexpress,iis等一起运行。此外,在PROD中,服务器前通常有代理/网关。我认为最简单的方法是为应用基本网址创建一个配置值。

2

NPNelson答案适用于.Value.ToString()

var baseUrl = $"{this.Request.Scheme}://{this.Request.Host.Value.ToString()}{this.Request.PathBase.Value.ToString()}";

4
ToString在这里没有帮助。它string.Format已经自动完成。
Patrick Hofman

1
var baseUrl = Request.GetTypedHeaders().Referer.ToString();

这样,您可以捕获基本URL信息。

这就是我如何在Asp .Net Core 3.1版本中获得它的方法。

您可以从下面的链接访问资源。

参考


0
using Microsoft.AspNetCore.Http;    

public void ConfigureServices(IServiceCollection services)
{
     services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
    
    
public AccountController(IHttpContextAccessor httpContextAccessor)
{
     var request = httpContextAccessor.HttpContext.Request;
     var domain = $"{request.Scheme}://{request.Host}";
     //domain => https://varunsoft.in
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.