ASP.NET Core 6.0+:如何获取当前(区分大小写)的IIS网站名称?

ASP.NET Core 6.0+: How to get the current (case-sensitive) IIS Website Name?

我正在尝试获取我在 IIS 中托管的 ASP.NET 6 应用程序的名称。我需要的正是这个带有适当大小写的名称:

在 .NET Framework 4.8 中,此名称由 HttpRequest.ApplicationPath 提供,返回时带有正确的大小写(如在 IIS 中配置的那样,而不是在即将到来的请求的 URL 中)。但是,它在 .NET 6 中不存在。

我试过了:

有谁知道如何获取此网站在 IIS 中配置的名称(使用正确的大小写)?

长话短说:

像这样:

// This code assumes HttpContext is available, such as in a Middleware method or `Controller` subclass.

using Microsoft.AspNetCore.Http;

String? iisMetabasePath = httpContext.GetServerVariable("APPL_MD_PATH");

// or (long-form):

String? iisMetabasePath = HttpContextServerVariableExtensions.GetServerVariable( httpContext, "APPL_MD_PATH" );

然后 trim-off /LM/W3SVC/ 部分。

请注意,当您 运行 您的代码在 IIS 之外时,例如使用 ASP.NET Core 的开发服务器,所有 IIS-specific 数据,例如 "APPL_MD_PATH" 都不会可用,因此请确保您也在处理这种情况。


原始研究:ApplicationRoot发生了什么事?

是时候 bust-out ILSpy 了...

  1. HttpRequest.ApplicationPathHttpRuntime.AppDomainAppVirtualPath.
  2. HttpRuntime.AppDomainAppVirtualPathVirtualPath.GetVirtualPathStringNoTrailingSlash(HttpRuntime._theRuntime._appDomainAppVPath).
  3. HttpRuntime._theRuntime._appDomainAppVPath设置在HttpRuntime.Init().
  4. HttpRuntime.Init()HttpRuntime.GetAppDomainString(".appVPath")) 设置 _appDomainAppVPath
  5. System.Web.Hosting.ApplicationManager::PopulateDomainBindingsdict.Add(".appVPath", appVPath.VirtualPathString)
    • “域绑定”在此上下文中指的是 AppDomain 绑定:与 DNS domain-names 或 Host header 完全无关IIS 中的绑定。是的,超载的术语。
  6. PopulateDomainBindingsSystem.Web.Hosting.ApplicationManager::CreateAppDomainWithHostingEnvironment 调用。
    • 它得到 virtualPath: VirtualPath.Create(appHost.GetVirtualPath())
  7. appHost.GetVirtualPath()IApplicationHost.GetVirtualPath()
    • 有 2 个 in-box 实现:System.Web.Hosting.ISAPIApplicationHostSystem.Web.Hosting.SimpleApplicationHost。我们对 ISAPIApplicationHost.
    • 感兴趣
  8. ISAPIApplicationHostIAppManagerAppDomainFactory.Create 方法中 String appIdString appPath 的 运行time 参数获取其 virtualPath。
    • IAppManagerAppDomainFactory是IIS直接使用的COM接口。
      • 剧情变厚了...
  9. 此时我迷路了 through the legacy IIS 6 ISAPI documentation,寻找 IAppManagerAppDomainFactory 的原始 COM 定义的踪迹,但找到了 empty-handed。
    • 它可能由 webengine4.dll 处理,它是一个本机 DLL,我现在没有时间 bust-out Ghidra...
    • 我确实注意到 ISAPI 请求 entrypoint method HttpExtensionProc (and its LPEXTENSION_CONTROL_BLOCK parameter) 包含 IIS 应用程序范围 AppId 或虚拟路径,它让我感到惊讶 - 但最重要的是:这表明该值可能来自 GetServerVariableServerSupportFunction 回调....
    • 然而,这可能是浪费时间 IIS 6 是 不是 IIS7+ 并且 IIS7+ 的接口 no-longer 称为“ISAPI”,但仅称为“IIS Native-Code API”(这是我最近看到的最平淡无奇的API名字了...)。
  10. 因此,从 “IIS Native-Code API” 文档 I quickly found the IWpfApplicationInfoUtil::GetApplicationPropertiesFromAppId method (here "WPF" means "Worker Process Framework”开始,与 其他 UI-related WPF)。
    • 我还发现暴露了相同的数据 via the IMetadataInfo.GetMetaPath() method(returns 形式为 "LM/WEBROOT/AppHost/{SiteId}" 的字符串)。
    • 那么应用程序如何获得IWpfApplicationInfoUtil接口引用呢?
  11. Actually AspNetCoreModuleV2 uses IIS's IHttpApplication, derp
  12. 在这一点上我放弃了,因为它现在是 6:20am,但那是一次有趣的潜水!