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

Daw*_*ski 2 c# asp.net iis asp.net-core .net-6.0

我正在尝试获取 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 中配置的站点名称(使用正确的大小写)?

Dai*_*Dai 5

长话短说:

就像这样:

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

然后把这个部分剪掉就可以了/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._appDomainAppVPath安顿好了HttpRuntime.Init()
  4. HttpRuntime.Init()_appDomainAppVPathHttpRuntime.GetAppDomainString(".appVPath")).
    • “AppDomain 字符串”每个AppDomain.
    • 一般来说,.NET Framework(又名 )中的 ASP.NET 为IIS 中的每个应用程序范围System.Web创建一个新的应用程序范围。AppDomain
    • 当然,AppDomains在 .NET Core 及更高版本中不再存在
    • 那么让我们找出String价值".appVPath"从何而来......
  5. System.Web.Hosting.ApplicationManager::PopulateDomainBindingsdict.Add(".appVPath", appVPath.VirtualPathString)
    • 本文中的“域绑定”指的是AppDomain 绑定:与 IIS 中的 DNS 域名或标头绑定完全无关Host。术语太多了。
  6. PopulateDomainBindings被称为System.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从方法中的运行String appId时参数获取其虚拟路径。 String appPathIAppManagerAppDomainFactory.Create
    • 并且IAppManagerAppDomainFactory是IIS直接使用的COM接口。
      • 剧情变得越来越浓重……
  9. 此时,我在遗留的 IIS 6 ISAPI 文档中迷失了方向,寻找原始 COM 定义的踪迹,IAppManagerAppDomainFactory但一无所获。
    • 它可能由webengine4.dll本机 DLL 处理,我现在没有时间破坏 Ghidra...
    • 我确实注意到 ISAPI 请求入口点方法HttpExtensionProc(及其LPEXTENSION_CONTROL_BLOCK参数包含 IIS 应用程序范围AppId或虚拟路径,这让我感到惊讶 - 但最重要的是:这表明该值可能来自GetServerVariableServerSupportFunction回调......
    • 然而,无论如何,这可能是浪费时间,IIS 6 不是IIS7 +,并且 IIS7+ 的接口不再称为“ISAPI”,而只是称为“IIS Native-Code API”(这是我在尽管...)。
  10. 因此,从“IIS Native-Code API”文档开始,我很快找到了IWpfApplicationInfoUtil::GetApplicationPropertiesFromAppId方法(这里“WPF”的意思是“ Worker Process Framework ”,与其他UI相关的WPF完全无关)。
  11. 实际上AspNetCoreModuleV2使用IIS的IHttpApplicationderp
  12. 此时我放弃了,因为现在是早上 6:20,但那是一次有趣的潜水!