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

Posted

技术标签:

【中文标题】如何在 ASP.NET Core 中获取我网站的 baseurl?【英文标题】:How can I get the baseurl of my site in ASP.NET Core? 【发布时间】:2017-04-20 17:56:06 【问题描述】:

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

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

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

【问题讨论】:

@VSO 如果您查看 OP 链接的答案,您将看到核心的更新版本,您应该能够将其转换为服务,以便您可以在应用程序中的任何位置访问请求请求的范围。 ***.com/a/12144292/5233410 这个问题提供的答案是正确的。你有什么不明白的? 【参考方案1】:

你应该仍然能够拼凑你需要的东西。如果您的控制器继承自 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.Hostthis.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 地址。

【讨论】:

应该是 Request.Scheme + "://" + Request.Host + Request.PathBase 我更新了我的答案以使用 PathBase 而不是 Path。感谢 Tratcher 指出这一点。 我想指出这是多么糟糕的想法。用户可以更改“Url.Request”。不要在用户信息附近的任何地方使用它。想象一个精心设计的“忘记密码”请求。 如果我附加 .Value.ToString() $"this.Request.Scheme://this.Request.Host.Value.ToString()this.Request.PathBase.值.ToString()"; 经过考虑,我认为这个值实际上很容易在不知道它最初来自(可能是恶意的)用户输入的情况下被存储和稍后使用。我实施了一个白名单来缓解这种情况。或者,使用此 baseurl 的客户端也可以向服务器发出某种挑战。【参考方案2】:

如果您在应用程序的任何地方都需要它,那么您应该创建一个类并将其添加为服务。 像这样定义静态类和扩展方法,以便将其添加到服务管道中。

public class MyHttpContext

    private static IHttpContextAccessor m_httpContextAccessor;

    public static HttpContext Current => m_httpContextAccessor.HttpContext;

    public static string AppBaseUrl => $"Current.Request.Scheme://Current.Request.HostCurrent.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 中的 Configure 方法中的管道中

app.UseHttpContext()

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

var appBaseUrl = MyHttpContext.AppBaseUrl;

【讨论】:

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

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

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

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

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

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

【讨论】:

与 .NET 6 配合得很好?【参考方案4】:

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

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

【讨论】:

ToString 在这里没有帮助。它已经由string.Format 自动完成。【参考方案5】:
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

【讨论】:

【参考方案6】:
var baseUrl = Request.GetTypedHeaders().Referer.ToString();

这样你就可以捕获基本的url信息了。

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

您可以通过以下链接访问资源。

Reference

【讨论】:

感谢您的提示,它可能在某些情况下有效,但并非在任何地方都有效,例如启动:app.UseExceptionHandler。使用 $"context.Request.Scheme://context.Request.Hostcontext.Request.Path";【参考方案7】:
string.Format("0://12", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));

您可以在此处查看更多信息: How can I get my webapp's base URL in ASP.NET MVC?

【讨论】:

我可能弄错了,但我相信这在 .NET Core 中不起作用。我来这里是因为 Request.Url 不可用。 在 ASP.Net Core 中不起作用。 OP 专门要求 ASP.Net Core

以上是关于如何在 ASP.NET Core 中获取我网站的 baseurl?的主要内容,如果未能解决你的问题,请参考以下文章

使用 JWT 令牌的 ASP.NET Core 网站到 WebApi 身份验证

如何将针对 net452 项目的 ASP.NET Core 部署为 IIS 中网站的 IIS 应用程序

如何在 ASP.NET Core 5 MVC (.NET 5) 中获取记录的用户数据?

ASP.Net Core 如何在 EF Core 和 Identity 中获取用户角色

如何在 ASP.NET Core 中获取没有构造函数注入的注入服务的实例?

如何在 Asp .Net Core SignalR Hub 中获取不记名令牌?