Поделиться через


Миграция с ASP.NET Core 2.2.x на 3.0

Скотт Адди и Рик Андерсон

В этой статье объясняется, как обновить существующий проект ASP.NET Core 2.2 до ASP.NET Core 3.0. Возможно, полезно создать новый проект ASP.NET Core 3.0 для:

  • Сравните с кодом ASP.NET Core 2.2.
  • Скопируйте соответствующие изменения в проект ASP.NET Core 3.0.

Предварительные условия

Обновление версии пакета SDK для .NET Core в global.json

Если решение использует global.json файл для целевой версии пакета SDK для .NET Core, обновите его version свойство до версии 3.0, установленной на компьютере:

{
  "sdk": {
    "version": "3.0.100"
  }
}

Обновление файла проекта

Обновление целевой платформы

ASP.NET Core 3.0 и более поздних версий запускаются только в .NET Core. Установите идентификатор целевой платформы (TFM) как netcoreapp3.0:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

Удаление устаревших ссылок на пакеты

Большое количество пакетов NuGet не создается для ASP.NET Core 3.0. Такие ссылки на пакеты должны быть удалены из файла проекта. Рассмотрим следующий файл проекта для веб-приложения ASP.NET Core 2.2:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App"/>
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
  </ItemGroup>

</Project>

Обновленный файл проекта для ASP.NET Core 3.0:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

Обновленный файл проекта ASP.NET Core 3.0:

  • В <PropertyGroup>:

  • В <ItemGroup>:

    • Microsoft.AspNetCore.App удален. Дополнительные сведения см. в справочнике по Framework в этом документе.
    • Microsoft.AspNetCore.Razor.Design удаляется и в списке пакетов, перечисленных ниже, которые больше не производятся.

Чтобы просмотреть полный список пакетов, которые больше не производятся, выберите «Развернуть список».

Щелкните, чтобы развернуть список пакетов, которые больше не создаются
  • Microsoft.AspNetCore
  • Microsoft.AspNetCore.All
  • Microsoft.AspNetCore.App
  • Microsoft.AspNetCore.Antiforgery
  • Microsoft.AspNetCore.Authentication
  • Microsoft.AspNetCore.Authentication.Abstractions
  • Microsoft.AspNetCore.Authentication.Cookies
  • Microsoft.AspNetCore.Authentication.Core
  • Microsoft.AspNetCore.Authentication.OAuth
  • Microsoft.AspNetCore.Authorization.Policy
  • Microsoft.AspNetCore.CookiePolicy
  • Microsoft.AspNetCore.Cors
  • Microsoft.AspNetCore.Diagnostics
  • Microsoft.AspNetCore.Diagnostics.HealthChecks
  • Microsoft.AspNetCore.HostFiltering
  • Microsoft.AspNetCore.Hosting
  • Microsoft.AspNetCore.Hosting.Abstractions
  • Microsoft.AspNetCore.Hosting.Server.Abstractions
  • Microsoft.AspNetCore.Http
  • Microsoft.AspNetCore.Http.Abstractions
  • Microsoft.AspNetCore.Http.Connections
  • Microsoft.AspNetCore.Http.Extensions
  • Microsoft.AspNetCore.HttpOverrides
  • Microsoft.AspNetCore.HttpsPolicy
  • Microsoft.AspNetCore.Identity
  • Microsoft.AspNetCore.Localization
  • Microsoft.AspNetCore.Localization.Routing
  • Microsoft.AspNetCore.Mvc
  • Microsoft.AspNetCore.Mvc.Abstractions
  • Microsoft.AspNetCore.Mvc.Analyzers
  • Microsoft.AspNetCore.Mvc.ApiExplorer
  • Microsoft.AspNetCore.Mvc.Api.Analyzers
  • Microsoft.AspNetCore.Mvc.Core
  • Microsoft.AspNetCore.Mvc.Cors
  • Microsoft.AspNetCore.Mvc.DataAnnotations
  • Microsoft.AspNetCore.Mvc.Formatters.Json
  • Microsoft.AspNetCore.Mvc.Formatters.Xml
  • Microsoft.AspNetCore.Mvc.Localization
  • Microsoft.AspNetCore.Mvc.Razor
  • Microsoft.AspNetCore.Mvc.Razor.ViewCompilation
  • Microsoft.AspNetCore.Mvc.RazorPages
  • Microsoft.AspNetCore.Mvc.TagHelpers
  • Microsoft.AspNetCore.Mvc.ViewFeatures
  • Microsoft.AspNetCore.Razor
  • Microsoft.AspNetCore.Razor. Среды выполнения
  • Microsoft.AspNetCore.Razor.Design
  • Microsoft.AspNetCore.ResponseCaching
  • Microsoft.AspNetCore.ResponseCaching.Abstractions
  • Microsoft.AspNetCore.ResponseCompression
  • Microsoft.AspNetCore.Rewrite
  • Microsoft.AspNetCore.Routing
  • Microsoft.AspNetCore.Routing.Abstractions
  • Microsoft.AspNetCore.Server.HttpSys
  • Microsoft.AspNetCore.Server.IIS
  • Microsoft.AspNetCore.Server.IISIntegration
  • Microsoft.AspNetCore.Server.Kestrel
  • Microsoft.AspNetCore.Server.Kestrel. Ядро
  • Microsoft.AspNetCore.Server.Kestrel. Https
  • Microsoft.AspNetCore.Server.Kestrel. Transport.Abstractions
  • Microsoft.AspNetCore.Server.Kestrel. Transport.Sockets
  • Microsoft.AspNetCore.Session
  • Microsoft.AspNetCore.SignalR
  • Microsoft.AspNetCore.SignalR.Core
  • Microsoft.AspNetCore.StaticFiles
  • Microsoft.AspNetCore.WebSockets
  • Microsoft.AspNetCore.WebUtilities
  • Microsoft.Net.Http.Headers

Просмотр критических изменений

Просмотр критических изменений

Справочник по фреймворку

Функции ASP.NET Core, доступные через один из пакетов, перечисленных выше, доступны в рамках Microsoft.AspNetCore.App общей платформы. Общая платформа — это набор сборок (DLL-файлы), которые установлены на компьютере, содержащий компонент среды выполнения и целевой пакет. Дополнительную информацию см. в этой публикации об общей платформе.

  • Проекты, предназначенные для пакета SDK Microsoft.NET.Sdk.Web, неявно ссылаются на платформу Microsoft.AspNetCore.App.

    Для этих проектов не требуются дополнительные ссылки:

    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
        ...
    </Project>
    
  • Проекты, которые ориентированы на Microsoft.NET.Sdk или Microsoft.NET.Sdk.Razor SDK, должны добавлять явный FrameworkReference к Microsoft.AspNetCore.App:

    <Project Sdk="Microsoft.NET.Sdk.Razor">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
      </ItemGroup>
        ...
    </Project>
    

Сборки, зависящие от фреймворка, с использованием Docker

Сборки, зависящие от платформы консольных приложений, использующих пакет, зависящий от общей платформы ASP.NET Core, могут привести к следующей ошибке среды выполнения:

It was not possible to find any compatible framework version
The specified framework 'Microsoft.AspNetCore.App', version '3.0.0' was not found.
  - No frameworks were found.

Microsoft.AspNetCore.App является общей платформой, содержащей среду выполнения ASP.NET Core и присутствует только на образе dotnet/core/aspnet Docker. Пакет SDK 3.0 уменьшает размер зависимых от платформ сборок с помощью ASP.NET Core, не включая дубликаты библиотек, доступных в общей платформе. Это потенциальная экономия до 18 МБ, но требуется, чтобы среда выполнения ASP.NET Core присутствовала / установлена для запуска приложения.

Чтобы определить, имеет ли приложение зависимость (прямое или косвенное) в общей платформе ASP.NET Core, изучите runtimeconfig.json файл, созданный во время сборки или публикации приложения. Следующий JSON-файл показывает зависимость от общей платформы ASP.NET Core:

{
  "runtimeOptions": {
    "tfm": "netcoreapp3.0",
    "framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "3.0.0"
    },
    "configProperties": {
      "System.GC.Server": true
    }
  }
}

Если приложение использует Docker, используйте базовый образ, включающий ASP.NET Core 3.0. Например, docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0.

Добавьте ссылки на пакеты для удаленных сборок

ASP.NET Core 3.0 удаляет некоторые сборки, которые ранее были частью Microsoft.AspNetCore.App ссылки на пакет. Чтобы визуализировать сборки, которые были удалены, сравните две общие папки платформы. Например, сравнение версий 2.2.7 и 3.0.0:

Сравнение сборок общей платформы

Чтобы продолжить использование функций, предоставляемых удаленными сборками, ознакомьтесь с версиями 3.0 соответствующих пакетов:

  • Для создания шаблона веб-приложения с отдельными учетными записями пользователей требуется добавить следующие пакеты:

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <UserSecretsId>My-secret</UserSecretsId>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.0.0" />
        <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
        <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0" />
      </ItemGroup>
    
    </Project>
    
  • Microsoft.EntityFrameworkCore

    Дополнительные сведения о ссылке на пакет поставщика базы данных см. в разделе "Поставщики баз данных".

  • Identity Пользовательского интерфейса

    Identity Поддержку пользовательского интерфейса можно добавить, ссылаясь на пакет Microsoft.AspNetCore.Identity.UI.

  • Службы SPA

  • Проверка подлинности. Поддержка сторонних потоков проверки подлинности доступна в виде пакетов NuGet:

  • Поддержка форматирования и согласования содержимого для System.Net.HttpClient: Пакет NuGet Microsoft.AspNet.WebApi.Client обеспечивает удобное расширение System.Net.HttpClient с помощью таких API, как ReadAsAsync и PostJsonAsync. Однако этот пакет зависит от Newtonsoft.Json, а не от System.Text.Json. Это означает, например, что имена свойств сериализации, указанные JsonPropertyNameAttribute (System.Text.Json), игнорируются. Существует более новый пакет NuGet, который содержит аналогичные методы расширения, но использует System.Text.Json: System.Net.Http.Json.

  • Razor компиляция среды выполнения. Поддержка компиляции представлений Razor и страниц среды выполнения теперь является частью Microsoft.AspNetCore.Mvc.Razor. RuntimeCompilation.

  • Поддержка MVC Newtonsoft.Json (Json.NET): возможность использования MVC с Newtonsoft.Json теперь является частью Microsoft.AspNetCore.Mvc.NewtonsoftJson.

Изменения при запуске

На следующем рисунке показаны удаленные и измененные строки в веб-приложении ASP.NET Core 2.2 Razor Pages:

удаленные и измененные строки в веб-приложении ASP.NET Core 2.2 Razor

На предыдущем рисунке удаленный код отображается красным цветом. Удаленный код не отображает cookie код параметров, который был удален до сравнения файлов.

На следующем рисунке показаны добавленные и измененные строки в веб-приложении ASP.NET Core 3.0 Razor Pages:

добавленные и измененные строки в веб-приложении ASP.NET Core 3.0 Razor

На предыдущем изображении добавленный код отображается зеленым цветом. Дополнительные сведения о следующих изменениях:

  • services.AddMvc до services.AddRazorPages, см. регистрацию службы MVC в этом документе.
  • CompatibilityVersion, см. версию совместимости для ASP.NET Core MVC.
  • IHostingEnvironment до IWebHostEnvironment см. это объявление на GitHub.
  • app.UseAuthorization добавлено в шаблоны для того, чтобы показать, как должен быть добавлен посреднический слой авторизации заказа. Если приложение не использует авторизацию, можно безопасно удалить вызов app.UseAuthorization.
  • app.UseEndpoints, см. статью Razor Pages или Migrate Startup.Configure в этом документе.

Поддержка анализатора

Проекты, нацеленные на Microsoft.NET.Sdk.Web, неявно ссылаются на анализаторы, ранее выпущенные в составе пакета Microsoft.AspNetCore.Mvc.Analyzers. Для их включения дополнительные ссылки не требуются.

Если приложение использует анализаторы API, ранее отправленные с помощью пакета Microsoft.AspNetCore.Mvc.Api.Analyzers, измените файл проекта, чтобы ссылаться на анализаторы, отправленные в составе веб-пакета SDK для .NET Core:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
    </PropertyGroup>

    ...
</Project>

Razor библиотека классов

Razor Проекты библиотеки классов, предоставляющие компоненты пользовательского интерфейса для MVC, должны задать AddRazorSupportForMvc свойство в файле проекта:

<PropertyGroup>
  <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>

Модель внутрипроцессного размещения

По умолчанию проекты используют модель размещения in-process в ASP.NET Core 3.0 или более поздних версиях. При необходимости можно удалить <AspNetCoreHostingModel> свойство в файле проекта, если его значение равно InProcess.

Kestrel

Настройка

Миграция Kestrel конфигурации в создатель веб-хостов, предоставленный ConfigureWebHostDefaults (Program.cs):

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        });

Если приложение создает узел вручную с помощью ConfigureWebHost вместо ConfigureWebHostDefaults, вызовите в построителе веб-узлов UseKestrel.

public static void Main(string[] args)
{
    var host = new HostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder.UseKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseIISIntegration()
            .UseStartup<Startup>();
        })
        .Build();

    host.Run();
}

Промежуточное ПО для подключения заменяет адаптеры подключения

Адаптеры подключения (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter) удалены из Kestrel. Замените адаптеры подключений на промежуточное ПО подключения. Промежуточное ПО для подключения похоже на промежуточное ПО HTTP в рамках ASP.NET Core, но предназначено для подключений более низкого уровня. Ведение журнала HTTPS и подключения:

  • Они были перемещены из адаптеров подключения в промежуточное ПО подключения.
  • Эти методы расширения работают как в предыдущих версиях ASP.NET Core.

См. для получения дополнительных сведений пример TlsFilterConnectionHandler в разделе ListenOptions.Protocols статьи.

Абстракции транспорта перемещаются и становятся общедоступными

Транспортный уровень Kestrel представлен как публичный интерфейс в Connections.Abstractions. В рамках этих обновлений:

  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions и ассоциированные типы были удалены.
  • NoDelay был перемещен из ListenOptions варианта транспорта.
  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode удален из KestrelServerOptions.

Дополнительные сведения см. в следующих ресурсах GitHub:

Kestrel Запрос заголовков трейлера

Для приложений, предназначенных для более ранних версий ASP.NET Core:

  • Kestrel добавляет заголовки фрагментированного трейлера HTTP/1.1 в коллекцию заголовков запросов.
  • Трейлеры доступны после того, как текст запроса считывается до конца.

Это вызывает некоторые опасения по поводу неоднозначности между заголовками и трейлерами, поэтому трейлеры были перемещены в новую коллекцию (RequestTrailerExtensions) в 3.0.

Трейлеры запросов HTTP/2:

  • Недоступно в ASP.NET Core 2.2.
  • Доступно в версии 3.0 как RequestTrailerExtensions.

Новые методы расширения запроса присутствуют для доступа к этим трейлерам. Как и в случае с HTTP/1.1, трейлеры доступны после того, как текст запроса считывается до конца.

Для выпуска 3.0 доступны следующие RequestTrailerExtensions методы:

  • GetDeclaredTrailers: получает заголовок запроса Trailer , в котором перечислены трейлеры, которые следует ожидать после текста.
  • SupportsTrailers: указывает, поддерживает ли запрос получение заголовков трейлера.
  • CheckTrailersAvailable: проверяет, поддерживает ли запрос трейлеры и доступны ли они для чтения. Эта проверка не предполагает, что есть трейлеры для чтения. Может не быть трейлеров для чтения, даже если true возвращается этим методом.
  • GetTrailer: получает запрошенный заключительный заголовок из ответа. Проверьте SupportsTrailers перед вызовом GetTrailer, или может произойти ошибка NotSupportedException, если запрос не поддерживает замыкающие заголовки.

Для получения дополнительной информации см. раздел Перенос трейлеров запроса в отдельную коллекцию (dotnet/AspNetCore #10410).

AllowSynchronousIO отключен

AllowSynchronousIO включает или отключает синхронные API ввода-вывода, например HttpRequest.Body.Read, HttpResponse.Body.Writeи Stream.Flush. Эти API являются источником нехватки потоков, что приводит к сбою приложения. В 3.0 AllowSynchronousIO отключен по умолчанию. Дополнительные сведения см. в разделе "Синхронный ввод-вывод" в статьеKestrel.

Если требуется синхронный ввод-вывод, его можно включить, настроив AllowSynchronousIO параметр на используемом сервере (например, при вызове ConfigureKestrel, если используется Kestrel). Обратите внимание, что все серверы (KestrelhttpSys, TestServer и т. д.) имеют собственный AllowSynchronousIO вариант, который не влияет на другие серверы. Синхронный ввод-вывод можно включить для всех серверов на основе каждого запроса с помощью IHttpBodyControlFeature.AllowSynchronousIO параметра:

var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();

if (syncIOFeature != null)
{
    syncIOFeature.AllowSynchronousIO = true;
}

Если у вас возникли проблемы с TextWriter реализациями или другими потоками, которые вызывают синхронные API в Dispose, используйте API DisposeAsync вместо этого.

Дополнительные сведения см. в разделе [Объявление] AllowSynchronousIO отключен на всех серверах (dotnet/AspNetCore #7644).

Буферизация форматировщика вывода

Newtonsoft.Json, XmlSerializer и DataContractSerializer основанные форматировщики поддерживают только синхронную сериализацию. Чтобы разрешить этим модулям форматирования работать с ограничениями AllowSynchronousIO сервера, MVC буферизирует выходные данные этих средств форматирования перед записью на диск. В результате буферизации MVC будет включать заголовок Content-Length при реагировании на эти средства форматирования.

System.Text.Json поддерживает асинхронную сериализацию и, следовательно, форматировщик на основе System.Text.Json не использует буфер. Рассмотрите возможность использования этого средства форматирования для повышения производительности.

Чтобы отключить буферизацию, приложения могут настроить SuppressOutputFormatterBuffering в запуске:

services.AddControllers(options => options.SuppressOutputFormatterBuffering = true)

Обратите внимание, что это может привести к тому, что приложение создает исключение среды выполнения, если AllowSynchronousIO не настроено.

Microsoft.AspNetCore.Server.Kestrel. Удалена сборка https

В ASP.NET Core 2.1 содержимое Microsoft.AspNetCore.Server.Kestrel.Https.dll было перемещено в Microsoft.AspNetCore.Server.Kestrel.Core.dll. Это было непрерывающее обновление с использованием атрибутов TypeForwardedTo. Для версии 3.0 пустая сборка Microsoft.AspNetCore.Server.Kestrel.Https.dll и пакет NuGet были удалены.

Библиотеки, ссылающиеся на Microsoft.AspNetCore.Server.Kestrel.Https должны обновлять зависимости ASP.NET Core до версии 2.1 или более поздней.

Приложения и библиотеки, предназначенные для ASP.NET Core 2.1 или более поздней версии, должны удалять любые прямые ссылки на пакет Microsoft.AspNetCore.Server.Https.

Поддержка Newtonsoft.Json (Json.NET)

В рамках работы по улучшению общей платформы ASP.NET Core newtonsoft.Json (Json.NET) было удалено из общей платформы ASP.NET Core.

Сериализатор JSON по умолчанию для ASP.NET Core теперь System.Text.Json, что является новым в .NET Core 3.0. Рекомендуется использовать System.Text.Json , когда это возможно. Он обладает высокой производительностью и не требует дополнительных библиотек. Тем не менее, так как System.Text.Json это новое, в настоящее время может быть отсутствуют функции, необходимые вашему приложению. Дополнительные сведения см. в разделе "Миграция из Newtonsoft.Json в System.Text.Json".

Использование Newtonsoft.Json в проекте ASP.NET Core 3.0 SignalR

  • Установите пакет NuGet Microsoft.AspNetCore.Protocols.NewtonsoftJson.

  • На стороне клиента, выполните вызов метода AddNewtonsoftJsonProtocol на экземпляре HubConnectionBuilder.

    new HubConnectionBuilder()
        .WithUrl("/chathub")
        .AddNewtonsoftJsonProtocol(...)
        .Build();
    
  • На сервере свяжите вызов метода AddNewtonsoftJsonProtocol с вызовом метода AddSignalR в Startup.ConfigureServices:

    services.AddSignalR()
        .AddNewtonsoftJsonProtocol(...);
    

Использование Newtonsoft.Json в проекте MVC ASP.NET Core 3.0

  • Установите пакет Microsoft.AspNetCore.Mvc.NewtonsoftJson.

  • Обновите Startup.ConfigureServices, чтобы вызвать AddNewtonsoftJson.

    services.AddMvc()
        .AddNewtonsoftJson();
    

    AddNewtonsoftJson совместим с новыми методами регистрации службы MVC:

    • AddRazorPages
    • AddControllersWithViews
    • AddControllers
    services.AddControllers()
        .AddNewtonsoftJson();
    

    Newtonsoft.Json Параметры можно задать в вызове AddNewtonsoftJson:

    services.AddMvc()
        .AddNewtonsoftJson(options =>
               options.SerializerSettings.ContractResolver =
                  new CamelCasePropertyNamesContractResolver());
    

    Примечание. Если AddNewtonsoftJson метод недоступен, убедитесь, что установлен Microsoft.AspNetCore.Mvc.NewtonsoftJson пакет. Распространенная ошибка заключается в установке пакета Newtonsoft.Json вместо Microsoft.AspNetCore.Mvc.NewtonsoftJson пакета.

Дополнительные сведения см. в разделе "Добавление поддержки формата JSON на основе Newtonsoft.Json".

Регистрация службы MVC

ASP.NET Core 3.0 добавляет новые параметры для регистрации сценариев MVC внутри Startup.ConfigureServices.

Доступны три новых метода расширения верхнего уровня, связанных с сценариями IServiceCollection MVC. Шаблоны используют эти новые методы вместо AddMvc. Однако AddMvc продолжает вести себя так же, как и в предыдущих выпусках.

В следующем примере добавлена поддержка контроллеров и функций, связанных с API, но не представлений или страниц. Шаблон API использует этот код:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}

В следующем примере добавлена поддержка контроллеров, функций, связанных с API, и представлений, но не страниц. Шаблон веб-приложения (MVC) использует следующий код:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
}

В следующем примере добавлена поддержка Razor Pages и минимальная поддержка контроллера. Шаблон веб-приложения использует этот код:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
}

Новые методы также можно объединить. Следующий пример эквивалентен вызову AddMvc в ASP.NET Core 2.2:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();
}

Код запуска маршрутизации

Если приложение вызывает UseMvc или UseSignalR, переносите приложение в Endpoint Routing, если это возможно. Чтобы улучшить совместимость маршрутизации конечных точек с предыдущими версиями MVC, мы вернулись к некоторым изменениям в создании URL-адресов, представленных в ASP.NET Core 2.2. Если вы столкнулись с проблемами с маршрутизацией конечных точек в версии 2.2, ожидайте улучшения в ASP.NET Core 3.0 со следующими исключениями:

  • Если приложение реализует IRouter или наследует от Route, используйте DynamicRouteValuesTransformer в качестве замены.
  • Если приложение напрямую обращается RouteData.Routers к MVC для анализа URL-адресов, его можно заменить с помощью LinkParser.ParsePathByEndpointName.
    • Определите маршрут, дав ему имя.
    • Используйте LinkParser.ParsePathByEndpointName и передайте нужное имя маршрута.

Маршрутизация конечных точек поддерживает тот же синтаксис шаблона маршрута и функции разработки шаблонов маршрутов, что и IRouter. Маршрутизация конечных точек поддерживается IRouteConstraint. Маршрутизация конечных точек поддерживает [Route]и [HttpGet]другие атрибуты маршрутизации MVC.

Для большинства приложений изменения требуются только Startup.

Настройка миграции Startup.Configure

Общие советы:

  • Добавьте UseRouting.

  • Если приложение вызывает UseStaticFiles, разместите UseStaticFilesпередUseRouting.

  • Если приложение использует такие функции проверки подлинности и авторизации, как AuthorizePage или [Authorize], поместите вызов UseAuthentication и UseAuthorization: послеUseRouting, но перед UseCorsUseEndpoints:

    public void Configure(IApplicationBuilder app)
    {
      ...
    
      app.UseStaticFiles();
    
      app.UseRouting();
      app.UseCors();
    
      app.UseAuthentication();
      app.UseAuthorization();
    
      app.UseEndpoints(endpoints => {
         endpoints.MapControllers();
      });
    
  • Замените UseMvc или UseSignalR на UseEndpoints.

  • Если приложение использует сценарии CORS, такие как [EnableCors], поместите вызов UseCors перед любым другим программным обеспечением промежуточного слоя, использующим CORS (например, разместите UseCors перед UseAuthentication, UseAuthorization и UseEndpoints).

  • Замените IHostingEnvironment на IWebHostEnvironment и добавьте инструкцию using для пространства имен Microsoft.AspNetCore.Hosting.

  • Замените IApplicationLifetime на IHostApplicationLifetime в пространстве имен Microsoft.Extensions.Hosting.

  • Замените EnvironmentName на Environments (Microsoft.Extensions.Hosting пространство имен).

Следующий код является примером Startup.Configure в типичном приложении ASP.NET Core 2.2:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseAuthentication();

    app.UseSignalR(hubs =>
    {
        hubs.MapHub<ChatHub>("/chat");
    });

    app.UseMvc(routes =>
    {
        routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

После обновления предыдущего Startup.Configure кода:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseRouting();

    app.UseCors();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chat");
        endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

Предупреждение

Для большинства приложений вызовы UseAuthentication, UseAuthorization и UseCors должны происходить между вызовами UseRouting и UseEndpoints, чтобы быть эффективными.

Проверки состояния здоровья

Для проверок работоспособности используется маршрутизация конечных точек с общим хостом. В Startup.Configure вызовите MapHealthChecks для построителя конечной точки с URL-адресом конечной точки или относительным путем:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
});

Конечные точки проверки работоспособности могут:

  • указать один или несколько разрешенных узлов или портов;
  • требовать авторизацию;
  • Требовать CORS.

Дополнительные сведения см. в статье Проверки работоспособности в ASP.NET Core.

Руководство по промежуточному программному обеспечению безопасности

Поддержка авторизации и CORS унифицируется с использованием подхода middleware. Это позволяет использовать одно и то же ПО промежуточного слоя и функциональные возможности в этих сценариях. Обновленное ПО промежуточного слоя авторизации предоставляется в этом выпуске, а ПО промежуточного слоя CORS улучшено, чтобы понять атрибуты, используемые контроллерами MVC.

CORS

Ранее CORS может быть сложно настроить. Программное обеспечение для промежуточного уровня предоставлялось для использования в некоторых случаях, но в других случаях фильтры MVC предназначены для использования без промежуточного ПО. В ASP.NET Core 3.0 рекомендуется во всех приложениях, требующих CORS, использовать CORS посредством промежуточного слоя в тандеме с маршрутизацией конечных точек. UseCors можно предоставить политику по умолчанию, а [EnableCors][DisableCors] атрибуты можно использовать для переопределения политики по умолчанию, где это необходимо.

В следующем примере :

  • CORS активирован для всех конечных точек, использующих именованную политику default.
  • Класс MyController отключает CORS с атрибутом [DisableCors] .
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseCors("default");

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

[DisableCors]
public class MyController : ControllerBase
{
    ...
}

Авторизация

В более ранних версиях ASP.NET Core поддержка авторизации была предоставлена через [Authorize] атрибут. Промежуточное ПО авторизации было недоступно. В ASP.NET Core 3.0 требуется промежуточное ПО авторизации. Рекомендуется размещать промежуточное программное обеспечение ASP.NET Core Authorization (UseAuthorization) сразу после UseAuthentication. Промежуточное программное обеспечение для авторизации также можно настроить с политикой по умолчанию, которую можно переопределить.

В ASP.NET Core 3.0 или более поздних версиях UseAuthorization вызывается в Startup.Configure, и для выполнения следующего HomeController требуется, чтобы пользователь был авторизован.

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

public class HomeController : Controller
{
    [Authorize]
    public IActionResult BuyWidgets()
    {
        ...
    }
}

При использовании маршрутизации конечных точек рекомендуется не настраивать AuthorizeFilter и полагаться на ПО промежуточного слоя авторизации. Если приложение использует AuthorizeFilter в качестве глобального фильтра в MVC, рекомендуется рефакторинг кода для предоставления политики в вызове AddAuthorization.

Изначально DefaultPolicy настроено так, что требуется аутентификация, поэтому дополнительная конфигурация не требуется. В следующем примере конечные точки MVC помечаются как RequireAuthorization, чтобы все запросы были авторизованы на основе DefaultPolicy. Однако доступ HomeController разрешен без входа пользователя в приложение из-за [AllowAnonymous]следующих особенностей:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute().RequireAuthorization();
    });
}

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

Авторизация для определенных конечных точек

Авторизацию также можно настроить для определенных классов конечных точек. Следующий код является примером конвертации приложения MVC, которое настраивает глобальное AuthorizeFilter на приложение с определенной политикой, требующей авторизации:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    static readonly string _RequireAuthenticatedUserPolicy = 
                            "RequireAuthenticatedUserPolicy";
    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        // Pre 3.0:
        // services.AddMvc(options => options.Filters.Add(new AuthorizeFilter(...));

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(o => o.AddPolicy(_RequireAuthenticatedUserPolicy,
                        builder => builder.RequireAuthenticatedUser()));

    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute()
                .RequireAuthorization(_RequireAuthenticatedUserPolicy);
            endpoints.MapRazorPages();
        });
    }
}

Политики также можно настроить. Для DefaultPolicy требуется настройка проверки подлинности:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
              .RequireAuthenticatedUser()
              .Build();
        });

    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute().RequireAuthorization();
            endpoints.MapRazorPages();
        });
    }
}
[AllowAnonymous]
public class HomeController : Controller
{

В качестве альтернативы, все конечные точки можно настроить для необходимости авторизации без [Authorize] или RequireAuthorization, используя FallbackPolicy. Отличается FallbackPolicy от DefaultPolicy. DefaultPolicy запускается [Authorize] или RequireAuthorization, в то время как FallbackPolicy активируется, когда не задана никакая другая политика. FallbackPolicy Изначально настроено разрешение запросов без авторизации.

Следующий пример совпадает с приведенным выше DefaultPolicy примером, но использует FallbackPolicy для обязательной аутентификации на всех конечных точках, за исключением тех случаев, когда указано [AllowAnonymous].

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddAuthorization(options =>
    {
        options.FallbackPolicy = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();
    });
}

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

Авторизация посредством промежуточного программного обеспечения работает без необходимости в конкретном понимании авторизации фреймворком. Например, проверки состояния здоровья не связаны напрямую с авторизацией, но они могут применять настраиваемую политику авторизации посредством промежуточного программного обеспечения.

Кроме того, каждая конечная точка может настраивать свои требования к авторизации. В следующем примере UseAuthorization обрабатывает авторизацию с помощью DefaultPolicy, но для проверки работоспособности конечной точки /healthz требуется пользователь admin.

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints
            .MapHealthChecks("/healthz")
            .RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin", });
    });
}

Защита реализуется для некоторых сценариев. Промежуточный слой для конечных точек вызывает исключение, если политика авторизации или CORS пропускается из-за отсутствия необходимого промежуточного слоя. Поддержка анализатора для предоставления дополнительных отзывов о неправильной настройке находится в процессе разработки.

Пользовательские обработчики авторизации

Если приложение использует пользовательские обработчики авторизации, маршрутизация конечных точек передает другой тип ресурсов обработчикам, отличным от MVC. Обработчики, ожидающие, что ресурс контекста обработчика авторизации будет иметь тип AuthorizationFilterContext (тип ресурса, предоставленный фильтрами MVC), необходимо обновить для обработки ресурсов типа RouteEndpoint (тип ресурса, заданный обработчикам авторизации путем маршрутизации конечных точек).

MVC по-прежнему использует AuthorizationFilterContext ресурсы, поэтому, если приложение использует фильтры авторизации MVC вместе с авторизацией маршрутизации конечных точек, может потребоваться обеспечить обработку обоих типов ресурсов.

SignalR

SignalR Сопоставление концентраторов теперь происходит внутри UseEndpoints.

Сопоставьте каждый концентратор с MapHub. Как и в предыдущих версиях, каждый концентратор явно указан.

В следующем примере добавлена поддержка концентратора ChatHubSignalR :

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>();
    });
}

Существует новый вариант управления ограничениями размера сообщений от клиентов. Например, для Startup.ConfigureServices:

services.AddSignalR(hubOptions =>
{
    hubOptions.MaximumReceiveMessageSize = 32768;
});

В ASP.NET Core 2.2 можно задать TransportMaxBufferSize и эффективно контролировать максимальный размер сообщения. В ASP.NET Core 3.0 этот параметр теперь управляет только максимальным размером до того, как будет наблюдаться обратное давление.

SignalR сборки в общем фреймворке

Серверные сборки ASP.NET Core SignalR теперь устанавливаются вместе с SDK для .NET Core. Дополнительные сведения см. в разделе "Удаление устаревших ссылок на пакеты" в этом документе.

Контроллеры MVC

Сопоставление контроллеров теперь происходит внутри UseEndpoints.

Добавьте MapControllers, если приложение использует маршрутизацию атрибутов. Поскольку маршрутизация включает поддержку множества фреймворков в ASP.NET Core 3.0 и более поздних версиях, добавление контроллеров с маршрутизацией по атрибутам происходит по желанию.

Замените следующее:

  • MapRoute с MapControllerRoute
  • MapAreaRoute с MapAreaControllerRoute

Поскольку маршрутизация теперь включает поддержку не только MVC, терминология изменилась, чтобы эти методы явно указывали, что именно они делают. Обычные маршруты, такие как MapControllerRoute/MapAreaControllerRoute/MapDefaultControllerRoute применены в порядке их добавления. Сначала поместите более конкретные маршруты (например, маршруты для области).

В следующем примере :

  • MapControllers добавляет поддержку контроллеров с маршрутизацией, управляемой атрибутами.
  • MapAreaControllerRoute добавляет стандартный маршрут для контроллеров в данной области.
  • MapControllerRoute добавляет обычный маршрут для контроллеров.
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapAreaControllerRoute(
            "admin",
            "admin",
            "Admin/{controller=Home}/{action=Index}/{id?}");
        endpoints.MapControllerRoute(
            "default", "{controller=Home}/{action=Index}/{id?}");
    });
}

Удаление асинхронного суффикса из имен действий контроллера

В ASP.NET Core 3.0 ASP.NET Core MVC удаляет Async суффикс из имен действий контроллера. Маршрутизация и создание ссылок затрагиваются этим новым значением по умолчанию. Например:

public class ProductsController : Controller
{
    public async Task<IActionResult> ListAsync()
    {
        var model = await _dbContext.Products.ToListAsync();
        return View(model);
    }
}

До ASP.NET Core 3.0:

  • К предыдущему действию можно получить доступ по маршруту Products/ListAsync .

  • Для создания ссылок необходимо указание суффикса Async. Например:

    <a asp-controller="Products" asp-action="ListAsync">List</a>
    

В ASP.NET Core 3.0:

  • К предыдущему действию можно получить доступ по маршруту Products/List .

  • Для создания ссылок не требуется указывать Async суффикс. Например:

    <a asp-controller="Products" asp-action="List">List</a>
    

Это изменение не влияет на имена, указанные с атрибутом [ActionName]. Поведение по умолчанию можно отключить с помощью следующего кода:Startup.ConfigureServices

services.AddMvc(options =>
    options.SuppressAsyncSuffixInActionNames = false);

Существуют некоторые различия в создании ссылок (например, с помощью Url.Link и аналогичных API). Например:

  • По умолчанию при использовании маршрутизации конечных точек регистр параметров маршрута в созданных URI не обязательно сохраняется. Это поведение можно контролировать с помощью IOutboundParameterTransformer интерфейса.
  • Создание URI для недопустимого маршрута (контроллер или действие или страница, которая не существует) создаст пустую строку в маршрутизации конечных точек вместо создания недопустимого URI.
  • Внешние значения (параметры маршрута из текущего контекста) не используются автоматически в создании ссылок с маршрутизацией конечных точек. Ранее, при создании ссылки на другое действие (или страницу), неопределенные значения маршрутов выводились из значений текущего маршрута. При использовании маршрутизации конечных точек все параметры маршрута должны быть явно указаны во время создания канала.

Razor Страницы

Сопоставление страниц Razor теперь осуществляется внутри UseEndpoints.

Добавьте MapRazorPages, если приложение использует страницы Razor. Так как маршрутизация конечных точек включает поддержку для многих платформ, добавление Razor Страницы теперь является опцией.

В следующем Startup.Configure методе MapRazorPages добавляется поддержка страниц Razor.

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Использование MVC без маршрутизации конечных точек

Использование MVC через UseMvcUseMvcWithDefaultRoute или в ASP.NET Core 3.0 требует явного согласия внутри Startup.ConfigureServices. Это необходимо, так как MVC должен знать, может ли он полагаться на авторизацию и ПО промежуточного слоя CORS во время инициализации. Предоставляется анализатор, который предупреждает, пытается ли приложение использовать неподдерживаемую конфигурацию.

Если приложению IRouter требуется устаревшая поддержка, отключите EnableEndpointRouting с помощью любого из следующих подходов в Startup.ConfigureServices.

services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddControllers(options => options.EnableEndpointRouting = false);
services.AddControllersWithViews(options => options.EnableEndpointRouting = false);
services.AddRazorPages().AddMvcOptions(options => options.EnableEndpointRouting = false);

Оценка состояния

Проверки работоспособности можно использовать в качестве компонента в составе маршрутизации конечных точек.

Добавьте MapHealthChecks для использования проверок работоспособности с маршрутизацией конечных точек. Метод MapHealthChecks принимает аргументы, аналогичные UseHealthChecks. Преимущество использования MapHealthChecksUseHealthChecks — возможность применения авторизации и более точного контроля над политикой сопоставления.

В следующем примере MapHealthChecks вызывается конечная точка проверки работоспособности по /healthzадресу:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/healthz", new HealthCheckOptions() { });
    });
}

HostBuilder заменяет WebHostBuilder

Шаблоны ASP.NET Core 3.0 используют Generic Host. Предыдущие версии использовали веб-узел. В следующем коде показан созданный Program класс шаблона ASP.NET Core 3.0:

// requires using Microsoft.AspNetCore.Hosting;
// requires using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

В следующем коде показан класс, созданный Program шаблоном ASP.NET Core 2.2:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

IWebHostBuilder остается в версии 3.0 и является типом webBuilder, как видно в предыдущем примере кода. WebHostBuilder будет не рекомендуется в будущем выпуске и заменен на HostBuilder.

Наиболее значительное изменение от WebHostBuilder к HostBuilder заключается во внедрении зависимостей (DI). При использовании HostBuilderможно внедрить только следующий код в Startupконструктор:

Ограничения DI HostBuilder:

  • Разрешите создание DI-контейнера только один раз.
  • Избегает возникающих проблем со временем существования объекта, таких как разрешение нескольких экземпляров одноэлементных объектов.

Дополнительные сведения см. в разделе "Избегание внедрения службы запуска" в ASP.NET Core 3.

AddAuthorization перемещено в другую сборку

Методы ASP.NET Core 2.2 и более ранние AddAuthorization в Microsoft.AspNetCore.Authorization.dll:

  • Переименованы AddAuthorizationCore.
  • Были перемещены в Microsoft.AspNetCore.Authorization.Policy.dll.

Приложения, использующие как Microsoft.AspNetCore.Authorization.dll, так и Microsoft.AspNetCore.Authorization.Policy.dll, не влияют.

Приложения, не использующие Microsoft.AspNetCore.Authorization.Policy.dll , должны выполнять одно из следующих действий:

  • Добавьте ссылку на Microsoft.AspNetCore.Authorization.Policy.dll. Этот подход подходит для большинства приложений и является обязательным.
  • Переключитесь на использование AddAuthorizationCore

Дополнительные сведения см. в статье о критических изменениях AddAuthorization(o =>в )перегрузке в другой сборке #386.

Identity Пользовательского интерфейса

Identity Обновления пользовательского интерфейса для ASP.NET Core 3.0:

  • Добавьте ссылку на пакет Microsoft.AspNetCore.UI.
  • Приложения, которые не используют Razor Pages, должны вызывать MapRazorPages. Смотрите Razor Страницы в этом документе.
  • Bootstrap 4 — это фреймворк пользовательского интерфейса по умолчанию. IdentityUIFrameworkVersion Задайте свойство проекта, чтобы изменить значение по умолчанию. Дополнительные сведения см. в этом объявлении GitHub.

SignalR

Клиент JavaScript изменился с @aspnet/signalr на @microsoft/signalr. Чтобы реагировать на это изменение, измените ссылки в package.json файлах, require инструкциях и инструкциях ECMAScript import .

System.Text.Json — это протокол по умолчанию

System.Text.Json Теперь используется протокол концентратора по умолчанию, используемый как клиентом, так и сервером.

В Startup.ConfigureServices вызовите AddJsonProtocol, чтобы задать параметры сериализатора.

Сервер:

services.AddSignalR(...)
        .AddJsonProtocol(options =>
        {
            options.PayloadSerializerOptions.WriteIndented = false;
        })

Клиент —

new HubConnectionBuilder()
    .WithUrl("/chathub")
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerOptions.WriteIndented = false;
    })
    .Build();

Переключитесь на Newtonsoft.Json

Если вы используете функции Newtonsoft.Json, которые не поддерживаются в System.Text.Json, вы можете вернуться в Newtonsoft.Json. См. статью SignalR ASP.NET Core 3.0 ранее в этой статье.

Распределенные кэши Redis

Пакет Microsoft.Extensions.Caching.Redis недоступен для приложений ASP.NET Core 3.0 или более поздних версий. Замените ссылку на пакет Microsoft.Extensions.Caching.StackExchangeRedis. Дополнительные сведения см. в статье Распределенное кэширование в ASP.NET Core.

Согласие на компиляцию во время выполнения

До ASP.NET Core 3.0 компиляция представлений во время выполнения была неявной функцией платформы. Компиляция среды выполнения дополняет компиляцию представлений во время сборки. Она позволяет платформе компилировать Razor представления и страницы (.cshtml файлы) при изменении файлов, не перестроив все приложение. Эта функция поддерживает сценарий быстрого редактирования в интегрированной среде разработки и обновления браузера для просмотра изменений.

В ASP.NET Core 3.0 компиляция среды выполнения — это сценарий согласия. Компиляция во время сборки — единственный механизм для компиляции представлений, включённого по умолчанию. Среда выполнения использует Visual Studio или dotnet-watch в Visual Studio Code для перестроения проекта при обнаружении изменений в .cshtml файлах. В Visual Studio изменения в файлах .cs, .cshtml или .razor в проекте, который выполняется (Ctrl+F5), но не отлаживается (F5), вызывают перекомпиляцию проекта.

Чтобы включить компиляцию среды выполнения в проекте ASP.NET Core 3.0:

  1. Установите пакет NuGet Microsoft.AspNetCore.Mvc.RuntimeCompilation.

  2. Обновите Startup.ConfigureServices, чтобы вызвать AddRazorRuntimeCompilation.

    Для ASP.NET Core MVC используйте следующий код:

    services.AddControllersWithViews()
        .AddRazorRuntimeCompilation(...);
    

    Для ASP.NET Core Razor Pages используйте следующий код:

    services.AddRazorPages()
        .AddRazorRuntimeCompilation(...);
    

На https://github.com/aspnet/samples/tree/main/samples/aspnetcore/mvc/runtimecompilation представлен пример условного включения компиляции среды выполнения в средах разработки.

Дополнительные сведения о Razor компиляции файлов см. в статье Razor о компиляции файлов в ASP.NET Core.

Перенос библиотек с помощью мультицелевого нацеливания

Библиотекам часто требуется поддержка нескольких версий ASP.NET Core. Большинство библиотек, скомпилированных в предыдущих версиях ASP.NET Core, должны продолжать работать без проблем. Для выполнения следующих условий требуется, чтобы приложение было скомпилировано несколькими способами:

  • Библиотека использует функцию, которая имеет двоичное критическое изменение.
  • Библиотека хочет воспользоваться новыми функциями в ASP.NET Core 3.0.

Например:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netcoreapp3.0;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" />
  </ItemGroup>
</Project>

Используйте #ifdefs для включения API ASP.NET Core 3.0:

var webRootFileProvider =
#if NETCOREAPP3_0
    GetRequiredService<IWebHostEnvironment>().WebRootFileProvider;
#elif NETSTANDARD2_0
    GetRequiredService<IHostingEnvironment>().WebRootFileProvider;
#else
#error unknown target framework
#endif

Дополнительные сведения об использовании api ASP.NET Core в библиотеке классов см. в разделе "Использование api ASP.NET Core" в библиотеке классов.

Прочие изменения

Система проверки в .NET Core 3.0 и более поздних версий рассматривает не допускающие значение NULL параметры или свойства привязки так, как если бы они имели атрибут [Required]. Дополнительные сведения см. в разделе [Обязательный] атрибут.

Публикация

Удалите папки bin и obj в каталоге проекта.

тестовый сервер

Для приложений, которые используют TestServer непосредственно с Generic Host, создайте TestServer на IWebHostBuilder в ConfigureWebHost:

[Fact]
public async Task GenericCreateAndStartHost_GetTestServer()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .Configure(app => { });
        })
    .StartAsync();

    var response = await host.GetTestServer().CreateClient().GetAsync("/");

    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

Нарушающие изменения API

Просмотрите важные изменения:

Маршрутизация конечных точек с параметром catch-all

Предупреждение

Соответствие параметра catch-all маршрутам может быть неправильным из-за ошибки в маршрутизации. Приложения, на работу которых влияет эта ошибка, обладают следующими характеристиками:

  • Маршрут универсальный, например {**slug}".
  • Маршрут catch-all не удаётся сопоставить с запросами, которые он должен сопоставлять.
  • После удаления других маршрутов маршрут catch-all начинает работать.

Ознакомьтесь с примерами 18677 и 16579, в которых встречается эта ошибка, на сайте GitHub.

Опциональное исправление для этой ошибки содержится в пакете SDK для .NET Core начиная с версии 3.1.301. Следующий код задает внутренний переключатель, исправляющий эту ошибку:

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

.NET Core 3.0 в службе приложение Azure

Развертывание .NET Core для службы приложений Azure завершено. .NET Core 3.0 доступен во всех центрах обработки данных служб приложений Azure.

модуль ASP.NET Core (ANCM)

Если модуль ASP.NET Core (ANCM) не был выбранным компонентом при установке Visual Studio или если в системе установлена предварительная версия ANCM, скачайте последнюю версию установщика пакета размещения .NET Core (прямая загрузка) и запустите установщик. Дополнительные сведения см. в разделе "Пакет размещения".