繁体   English   中英

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 中不存在。

我试过了:

  • HttpContext.Request.PathBase ,但它返回的路径与请求 URL 中的路径完全相同,而不是 IIS 中的路径
  • 注入IServerAddressesFeatureIWebHostEnvironment ,但它们都不包含来自 IIS 的名称以及正确的大小写
  • IServerAddressesFeature ,但也没有在此处找到任何相关内容
  • 获取服务器变量: IServerVariablesFeature serverVars = HttpContext.Features.Get<IServerVariablesFeature>()然后是 IIS 站点名称: string iis_version = serverVars["INSTANCE_NAME"] (参见此处的文档),但它以大写字母返回应用程序名称( MYSITE.WEB )

有谁知道如何获取在 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" );

然后只需修剪/LM/W3SVC/部分。

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


原创研究: ApplicationRoot发生了什么?

是时候淘汰ILSpy 了……

  1. HttpRequest.ApplicationPathHttpRuntime.AppDomainAppVirtualPath
  2. HttpRuntime.AppDomainAppVirtualPathVirtualPath.GetVirtualPathStringNoTrailingSlash(HttpRuntime._theRuntime._appDomainAppVPath)
  3. HttpRuntime._theRuntime._appDomainAppVPathHttpRuntime.Init()中设置。
  4. HttpRuntime.Init()HttpRuntime.GetAppDomainString(".appVPath"))设置_appDomainAppVPath
    • “AppDomain 字符串”是与每个AppDomain关联的小型可序列化标量值。
    • 一般来说,.NET 框架中的 ASP.NET(aka System.Web )为 IIS 中的每个应用程序 Scope创建一个新的AppDomain
    • 当然,AppDomains 不再存在于 .NET Core 及更高版本中。
    • 那么让我们找出".appVPath"String值从何而来……
  5. System.Web.Hosting.ApplicationManager::PopulateDomainBindings设置dict.Add(".appVPath", appVPath.VirtualPathString)
    • 此上下文中的“域绑定”指的是AppDomain 绑定:与 DNS 域名或 IIS 中的Host header 绑定完全无关。是的,重载术语。
  6. PopulateDomainBindingsSystem.Web.Hosting.ApplicationManager::CreateAppDomainWithHostingEnvironment调用。
    • 它得到virtualPath: VirtualPath.Create(appHost.GetVirtualPath())
  7. appHost.GetVirtualPath()IApplicationHost.GetVirtualPath()
    • 有 2 个内置实现: System.Web.Hosting.ISAPIApplicationHostSystem.Web.Hosting.SimpleApplicationHost 我们对ISAPIApplicationHost感兴趣。
  8. ISAPIApplicationHost从运行时参数到IAppManagerAppDomainFactory.Create方法中的String appIdString appPath appPath 获取其 virtualPath。
    • IAppManagerAppDomainFactory是IIS直接使用的一个COM接口。
      • plot加厚...
  9. 在这一点上,我在遗留的 IIS 6 ISAPI 文档中迷失了方向,寻找 IAppManagerAppDomainFactory 的原始IAppManagerAppDomainFactory定义的痕迹,但一无所获。
    • 它可能由webengine4.dll处理,它是原生的 DLL,我现在没有时间淘汰 Ghidra ...
    • 我确实注意到 ISAPI 请求入口点方法HttpExtensionProc (及其LPEXTENSION_CONTROL_BLOCK参数包含 IIS 应用程序 Scope AppId或虚拟路径,这让我感到惊讶 - 但最重要的是:这表明该值可能来自GetServerVariableServerSupportFunction回调。 ...
    • 然而,无论如何这可能是浪费时间 IIS 6不是IIS7+ 并且 IIS7+ 的接口不再称为“ISAPI”,而是仅称为“IIS Native-Code API”(这是我在尽管...)。
  10. 因此,从“IIS Native-Code API”文档开始, 我很快找到了IWpfApplicationInfoUtil::GetApplicationPropertiesFromAppId方法(这里的“WPF”表示“ Worker Process Framework ”,与其他与 UI 相关的 WPF 完全无关)。
    • 我还发现通过IMetadataInfo.GetMetaPath()方法公开的相同数据(该方法返回"LM/WEBROOT/AppHost/{SiteId}"形式的字符串)。
    • 那么应用程序如何获取IWpfApplicationInfoUtil接口引用呢?
      • IWorkerProcessFramework->GetWpfInterface(WPF_APPLICATION_INFO_UTIL_ID)->GetApplicationPropertiesFromAppId
  11. 实际上AspNetCoreModuleV2使用 IIS 的IHttpApplicationderp
  12. 此时我放弃了,因为现在是早上 6 点 20 分,但那是一次有趣的潜水!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM