共用方式為


System.Web 轉接器

dotnet/systemweb-adapters 存放庫中適配器的主要使用案例是協助在類別庫中依賴特定類型的開發人員,因為他們想要移轉到 ASP.NET Core。

配接器的一個重要功能是,它們允許在 ASP.NET Framework 和 ASP.NET Core 專案中都可以使用此函式庫。 將多個 ASP.NET Framework 應用程式更新為 ASP.NET Core 通常牽涉到中繼狀態,其中並非所有應用程式都已完整更新。 透過使用 System.Web 配接器,該函式庫皆可從 ASP.NET Core 和尚未升級的 ASP.NET Framework 呼叫端使用。

讓我們看看使用從 .NET Framework 移至 ASP.NET Core 的配接器範例。

套件

  • Microsoft.AspNetCore.SystemWebAdapters:此套件用於支援庫並提供您可能依賴的 System.Web API,例如 HttpContext 和其他。 此套件的目標為 .NET Standard 2.0、.NET Framework 4.5+和 .NET 5+。
  • Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices:此套件僅支援 .NET Framework,旨在為可能需要提供增量遷移的 ASP.NET Framework 應用程式提供服務。 通常預期不會從函式庫引用,而是直接由應用程式本身引用。
  • Microsoft.AspNetCore.SystemWebAdapters.CoreServices:此套件僅以 .NET 6+ 為目標,旨在為 ASP.NET Core 應用程式提供服務,以設定 System.Web API 的行為,並選擇加入任何增量移轉的行為。 通常預期不會從函式庫引用,而是直接由應用程式本身引用。
  • Microsoft.AspNetCore.SystemWebAdapters.Abstractions:此套件是支援套件,可為 ASP.NET Core 和 ASP.NET Framework 應用程式所使用的服務提供抽象概念,例如會話狀態串行化。

轉換成 System.Web.HttpContext

若要在 HttpContext 的兩種表示法之間進行轉換,您可以執行下列動作:

HttpContextHttpContext

  • 隱含轉型
  • HttpContext.AsSystemWeb()

HttpContextHttpContext

  • 隱含轉型
  • HttpContext.AsAspNetCore()

這兩種方法都會在請求期間使用快取的 HttpContext 表示法。 這允許根據需要對HttpContext進行有針對性的重寫。

範例

ASP.NET 框架

請考慮執行下列動作的控制器:

public class SomeController : Controller
{
  public ActionResult Index()
  {
    SomeOtherClass.SomeMethod(HttpContext.Current);
  }
}

接著,在一個獨立的組件中包含邏輯,將 HttpContext 傳遞直到最後,某些內部方法會對其進行一系列邏輯運算,例如:

public class Class2
{
  public bool PerformSomeCheck(HttpContext context)
  {
    return context.Request.Headers["SomeHeader"] == "ExpectedValue";
  }
}

ASP.NET Core

若要在 ASP.NET Core 中執行上述邏輯,開發人員必須新增 Microsoft.AspNetCore.SystemWebAdapters 套件,讓項目能夠在這兩個平台上運作。

函式庫需要更新,以便能夠理解配接器,但只需新增套件並重新編譯,就像那麼簡單。 如果這些是系統對System.Web.dll的唯一相依性,那麼程式庫就能夠以.NET Standard 2.0為目標,以促進在遷移過程中更簡單的建置流程。

ASP.NET Core 中的控制器現在看起來會像這樣:

public class SomeController : Controller
{
  [Route("/")]
  public IActionResult Index()
  {
    SomeOtherClass.SomeMethod(HttpContext);
  }
}

請注意,由於有 HttpContext 屬性,因此可以傳遞該屬性,但它的一般外觀並不會改變。 使用隱含轉換,可以將 HttpContext 轉換成適配器,然後通過使用程式碼在不同層級間進行傳遞。

單元測試

單元測試使用 System.Web 配接器的程式碼時,需要記住一些特殊考量。

在大部分情況下,不需要設定其他元件來執行測試。 但是,如果測試的元件使用 HttpRuntime,可能需要啟動 SystemWebAdapters 服務,如下列範例所示:

namespace TestProject1;

/// <summary>
/// This demonstrates an xUnit feature that ensures all tests
/// in classes marked with this collection are run sequentially.
/// </summary>
[CollectionDefinition(nameof(SystemWebAdaptersHostedTests),
    DisableParallelization = true)]
public class SystemWebAdaptersHostedTests
{
}
[Collection(nameof(SystemWebAdaptersHostedTests))]
public class RuntimeTests
{
    /// <summary>
    /// This method starts up a host in the background that
    /// makes it possible to initialize <see cref="HttpRuntime"/>
    /// and <see cref="HostingEnvironment"/> with values needed 
    /// for testing with the <paramref name="configure"/> option.
    /// </summary>
    /// <param name="configure">
    /// Configuration for the hosting and runtime options.
    /// </param>
    public static async Task<IDisposable> EnableRuntimeAsync(
        Action<SystemWebAdaptersOptions>? configure = null,
        CancellationToken token = default)
        => await new HostBuilder()
           .ConfigureWebHost(webBuilder =>
           {
               webBuilder
                   .UseTestServer()
                   .ConfigureServices(services =>
                   {
                       services.AddSystemWebAdapters();
                       if (configure is not null)
                       {
                           services.AddOptions
                               <SystemWebAdaptersOptions>()
                               .Configure(configure);
                       }
                   })
                   .Configure(app =>
                   {
                       // No need to configure pipeline for tests
                   });
           })
           .StartAsync(token);
    [Fact]
    public async Task RuntimeEnabled()
    {
        using (await EnableRuntimeAsync(options =>
            options.AppDomainAppPath = "path"))
        {
            Assert.True(HostingEnvironment.IsHosted);
            Assert.Equal("path", HttpRuntime.AppDomainAppPath);
        }
        Assert.False(HostingEnvironment.IsHosted);
    }
}

測試必須依序執行,而不是平行執行。 上述範例說明如何將 XUnit 的選項DisableParallelization設定為 true來達成此目的。 此設定會停用特定測試集合的平行執行,確保該集合內的測試會逐一執行,而不需要並行。