首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 技術深度剖析(六):ASP.NET 寄宿下 BaseAddress 配置失效之謎與解決方案

     編輯:關於.NET

前言:一個看似 Bug 的行為

在 ASP.NET 應用(非 IIS .svc 模式)中以配置檔設定 <baseAddresses>,建立 ServiceHost 卻拋出 InvalidOperationException:「找不到符合 scheme http 的基底位址」。同樣代碼移至 Console/WPF 應用卻正常運作。本文深入原始碼揭示根因並給出解決方案。

一、問題重現

<service name="CalculatorService">
  <host>
    <baseAddresses>
      <add baseAddress="https://127.0.0.1:3721/services" />
    </baseAddresses>
  </host>
  <endpoint address="calculatorservice" binding="wsHttpBinding" contract="CalculatorService" />
</service>

ASP.NET Page_Load 中 new ServiceHost(typeof(CalculatorService)) 即拋出異常。StackTrace 指向 ServiceHostBase.MakeAbsoluteUri 找不到 BaseAddress。

二、根因分析:HostingEnvironment.IsHosted 誤判

WCF 判斷寄宿環境的關鍵邏輯在 ServiceHostBase.LoadHostConfig:

if (!ServiceHostingEnvironment.IsHosted) // 僅非託管環境才載入 baseAddresses 配置
{
    // 載入 <baseAddresses> 並加入 baseAddresses 集合
}

ServiceHostingEnvironment.IsHosted 內部委派 HostingEnvironmentWrapper.IsHosted → System.Web.Hosting.HostingEnvironment.IsHosted。在任何 ASP.NET 應用(含 WebForm、MVC)中,此屬性永遠回傳 true。WCF 因此將 ASP.NET 自寄宿誤判為 IIS/WAS 寄宿,直接忽略配置檔中的 <baseAddresses>。

三、解決方案

方案 1:程式碼指定 BaseAddress(推薦)

protected void Page_Load(object sender, EventArgs e)
{
    _host = new ServiceHost(typeof(CalculatorService), 
        new Uri("https://127.0.0.1:3721/services"));
    _host.Open();
}

方案 2:端點使用絕對位址

<endpoint address="https://127.0.0.1:3721/services/calculatorservice" 
          binding="wsHttpBinding" contract="CalculatorService" />

總結

這本質上是 WCF 設計時將「ASP.NET 應用」等同於「IIS 寄宿」的決策導致。在 ASP.NET 自寄宿場景,請勿依賴配置檔 BaseAddress,改用建構函式傳入 Uri 或端點絕對位址。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved