如何在ASP.NET Core中获取我的站点的baseurl?

jao*_*jao 41 asp.net asp.net-core-mvc asp.net-core

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

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

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

NPN*_*son 73

你仍然可以拼凑你需要的东西.如果控制器继承,您可以访问请求对象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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我只是在"关于"方法中输入了一些您可能感兴趣的内容,但是您应该探索请求类的其余部分,以便了解其他可用内容.

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

  • 那应该是Request.Scheme +"://"+ Request.Host + Request.PathBase (2认同)
  • 我更新了我的答案,使用**PathBase**而不是**Path**.感谢Tratcher指出这一点. (2认同)
  • 我想指出这是一个多么糟糕的想法。用户可以更改“Url.Request”。不要在用户信息附近的任何地方使用它。想象一下精心设计的“忘记密码”请求。 (2认同)

Tob*_*s J 33

所有这些现有答案都依赖于一个HttpContext对象,该对象仅在传入请求期间可用。HttpContext但是,我需要在不可用的后台服务中获取 URL 。

该信息在服务中也可用Microsoft.AspNetCore.Hosting.Server.IServer,只要实际的主机服务提供该信息即可。如果您使用默认的 Kestrel 服务器,我发现确实提供了它。在进程内托管 IIS 或使用其他托管模型时,我尚未对此进行测试。

您需要获取 的实例IServer,然后查找.Features类型的条目IServerAddressesFeature。下面是直接从 获取 URL 的扩展方法IServiceProvider

using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;

public static ICollection<string> GetApplicationUrls(this IServiceProvider services)
{
    var server = services.GetService<IServer>();

    var addresses = server?.Features.Get<IServerAddressesFeature>();

    return addresses?.Addresses ?? Array.Empty<string>();
}
Run Code Online (Sandbox Code Playgroud)

IServer然而,如果 DI 服务可用,您可以通过注入来完成同样的事情。

  • 与 .NET 6 良好配合 (3认同)

Rob*_*Rob 18

如果您在应用程序中的任何位置需要它,那么您应该构建中间件.定义静态类和扩展方法,以便将中间件添加到服务管道中.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下暴露HttpContext可能有点多余,但我发现它非常有用.

您可以在Confupfure方法中将其添加到管道中,该方法位于Startup.cs中

app.UseHttpContext()
Run Code Online (Sandbox Code Playgroud)

从那里可以很容易地在代码中的任何地方使用它.

var appBaseUrl = MyHttpContext.AppBaseUrl;
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。还是一样。我在某处读到,因为 .NET Core 的托管方式,在完全启动之前它不会有服务器信息。我试图从 StartUp 中获取它。 (4认同)
  • @SruthiVarghese 我不认为你可以从启动时解析主机 url。我的理解是.NET Core都是控制台应用程序,您的启动决定它的托管方式。因此,相同的代码可以作为控制台、iisexpress、iis 等运行。此外,在 PROD 中,服务器前面通常有代理/网关。我认为最简单的方法就是为应用程序基本 url 创建一个配置值。 (3认同)
  • 如果您从控制器调用MyHttpContext.AppBaseUrl,这似乎是可行的。我需要在启动时紧靠app.UseHttpSettings()之后的基本URL。似乎HttpContext在其中为null。有什么想法吗?谢谢 (2认同)
  • 确保在ConfigureServices方法中调用services.AddHttpContextAccessor()。 (2认同)

小智 9

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
}
Run Code Online (Sandbox Code Playgroud)


hub*_*t17 6

如果使用 .Value.ToString(),NPNelson 答案就有效

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

  • `ToString` 在这里没有帮助。它已经由“string.Format”自动完成。 (9认同)