Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Основной вариант использования адаптеров в репозитории 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: этот пакет используется в вспомогательных библиотеках и предоставляет API System.Web, от которых вы могли бы зависеть, например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 для настройки поведения APISystem.Web, а также для включения любых дополнительных особенностей в процессе поэтапной миграции. Обычно не предполагается, что на это будут ссылаться из библиотек, а из самих приложений. -
Microsoft.AspNetCore.SystemWebAdapters.Abstractions. Этот пакет является вспомогательным пакетом, предоставляющим абстракции для служб, используемых как приложением ASP.NET Core, так и ASP.NET Framework, например сериализация состояния сеанса.
Преобразование в System.Web.HttpContext
Для преобразования между двумя представлениями HttpContext можно выполнить следующее:
Для HttpContext до HttpContext.
- Неявное приведение
HttpContext.AsSystemWeb()
Для HttpContext от HttpContext
- Неявное приведение
HttpContext.AsAspNetCore()
Оба этих метода будут использовать кэшированное HttpContext представление в течение длительности запроса. Это позволяет выполнять целевые перезаписи HttpContext по мере необходимости.
Пример
платформа ASP.NET
Рассмотрим контроллер, который выполняет такие действия, как:
public class SomeController : Controller
{
public ActionResult Index()
{
SomeOtherClass.SomeMethod(HttpContext.Current);
}
}
что затем приводит к тому, что логика в отдельной сборке передается между компонентами до тех пор, пока, наконец, какой-то внутренний метод не выполнит на этом некоторую логику, такую как:
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. Этот параметр отключает параллельное выполнение для определенной коллекции тестов, обеспечивая выполнение тестов в этой коллекции после другой без параллелизма.
ASP.NET Core