簡體   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