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


Миграция из ASP.NET Core в .NET 5 в .NET 6

В этой статье объясняется, как обновить существующий ASP.NET Core в проекте .NET 5 до .NET 6. Инструкции по миграции с ASP.NET Core 3.1 на .NET 6 см. в разделе "Миграция с ASP.NET Core 3.1 на .NET 6".

Предпосылки

Обновите версию .NET SDK в global.json

Если вы используете global.json файл для выбора определенной версии пакета SDK для .NET, обновите version свойство до установленной версии пакета SDK для .NET 6. Рассмотрим пример.

{
  "sdk": {
-    "version": "5.0.100"
+    "version": "6.0.100"
  }
}

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

Обновите идентификатор целевой платформы (TFM) в файле проекта на:net6.0

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

  <PropertyGroup>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

</Project>

Обновление ссылок на пакеты

В файле проекта обновите атрибут Microsoft.AspNetCore.* каждой ссылки Microsoft.Extensions.* и Version ссылки на пакет до версии 6.0.0 или более поздней. Рассмотрим пример.

<ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.3" />
-    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0" />
+    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="6.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
</ItemGroup>

Новая модель размещения

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

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

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Минимальная модель размещения:

  • Значительно сокращают количество файлов и строк кода, необходимых для создания приложения. Требуется только один файл с четырьмя строками кода.
  • Объединяют Startup.cs и Program.cs в один файл Program.cs.
  • Используют инструкции верхнего уровня для минимизации кода, необходимого для приложения.
  • Используют глобальные директивы using, чтобы исключить или минимизировать числу требуемых строк инструкций using.

В следующем коде отображаются Startup.cs и Program.cs файлы из шаблона .NET 5 для Web App (Razor Pages) с удаленными неиспользуемыми операторами using.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// Unused usings removed.

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

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
    }
}
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
// Unused usings removed.

namespace WebAppRPv5
{
    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>();
                });
    }
}

В ASP.NET Core в .NET 6 предыдущий код заменяется следующим кодом:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

В предыдущем примере ASP.NET Core в .NET 6 показано, как:

  • Происходит замена ConfigureServices на WebApplication.Services.
  • builder.Build() возвращает настроенную WebApplication переменную app. Configure заменяется вызовами конфигурации для тех же служб с использованием app.

Подробные примеры миграции ASP.NET Core в коде .NET 5 Startup в .NET 6 с использованием минимальной модели размещения приведены далее в этом документе.

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

- public string RequestId { get; set; }
+ public string? RequestId { get; set; }
  • Значения по умолчанию уровня журнала изменились в appsettings.json и appsettings.Development.json.
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"

В предыдущем коде шаблона ASP.NET Core "Microsoft": "Warning" был изменен на "Microsoft.AspNetCore": "Warning". Это изменение приводит к ведению журнала всех информационных сообщений из Microsoft пространства имен , кромеMicrosoft.AspNetCore. Например, Microsoft.EntityFrameworkCore теперь заносится в журнал на информационном уровне.

Дополнительные сведения о новой модели размещения см. в разделе " Часто задаваемые вопросы". Дополнительные сведения о внедрении типов ссылок, допускающих значение NULL (NRTs), и анализе нулевого состояния компилятора .NET см. в разделе "Типы ссылок, допускающие значение NULL (NRTs), и статический анализ нулевого состояния компилятора .NET".

Приложения, перенесенные в версию 6.0 или более поздней версии, не должны использовать новую модель минимального размещения

Использование Startup и Generic Host, который используется шаблонами ASP.NET Core 3.1 и 5.0, полностью поддерживается.

Использование запуска с новой минимальной моделью размещения

ASP.NET Core приложения версии 3.1 и 5.0 могут использовать свой Startup код с новой минимальной моделью хостинга. Использование Startup с минимальной моделью размещения имеет следующие преимущества:

  • Для вызова класса Startup не используется скрытая рефлексия.
  • Асинхронный код можно записать, так как разработчик управляет вызовом Startup.
  • Код можно написать так, чтобы он чередовал ConfigureServices и Configure.

Одно из незначительных ограничений при использовании Startup кода с новой минимальной моделью размещения заключается в том, что для внедрения зависимости в Configure необходимо вручную разрешить службу в Program.cs.

Рассмотрим следующий код, созданный шаблоном страниц ASP.NET Core 3.1 или 5.0 Razor Pages:

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>();
            });
}
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

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

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

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

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

Предыдущий код перенесен на новую минимальную модель размещения:

using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

var app = builder.Build();

startup.Configure(app, app.Environment);

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

    public IConfiguration Configuration { get; }

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

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (!env.IsDevelopment())
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

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

В приведенном выше коде блок if (env.IsDevelopment()) удаляется, так как в режиме разработки промежуточное программное обеспечение страницы исключений для разработчика включено по умолчанию. Дополнительные сведения см. в разделе "Различия между моделями размещения ASP.NET Core в .NET 5 и .NET 6" в следующем разделе.

При использовании настраиваемого контейнера внедрения зависимостей (DI) добавьте следующий выделенный код:

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

// Using a custom DI container.
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(startup.ConfigureContainer);

var app = builder.Build();

startup.Configure(app, app.Environment);

app.Run();
using Autofac;
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

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

    //  Using a custom DI container
    public void ConfigureContainer(ContainerBuilder builder)
    {
        // Configure custom container.
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (!env.IsDevelopment())
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

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

При использовании минимальной модели хостинга, промежуточное ПО маршрутизации конечных точек оборачивает весь конвейер промежуточного ПО, поэтому нет необходимости в явных вызовах UseRouting или UseEndpoints для регистрации маршрутов. UseRouting по-прежнему можно использовать для указания того, где происходит сопоставление маршрутов, но UseRouting не нужно явно вызывать, если маршруты должны сопоставляться в начале потока по промежуточному слою.

В следующем коде вызовы UseRouting и UseEndpoints удаляются из Startup. MapRazorPages вызывается в Program.cs:

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

    public IConfiguration Configuration { get; }

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

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (!env.IsDevelopment())
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        //app.UseRouting();

        //app.UseEndpoints(endpoints =>
        //{
        //    endpoints.MapRazorPages();
        //});
    }
}
using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

var app = builder.Build();

startup.Configure(app, app.Environment);

app.MapRazorPages();

app.Run();

При использовании Startup с новой минимальной моделью размещения следует учитывать следующее различие:

  • Program.cs управляет созданием и временем жизни класса Startup.
  • Любые дополнительные службы, внедренные в Configure метод, должны быть вручную разрешены классом Program .

Различия между ASP.NET Core в моделях размещения .NET 5 и .NET 6

  • В режиме разработки программный компонент для страниц исключений разработчика включен по умолчанию.
  • Имя приложения по умолчанию соответствует названию сборки точки входа: Assembly.GetEntryAssembly().GetName().FullName. При использовании WebApplicationBuilder в библиотеке необходимо явно изменить имя приложения на имя сборки библиотеки, чтобы позволить механизму обнаружения частей приложения MVC работать. Подробные инструкции см. в разделе "Изменение корневого каталога содержимого", имени приложения и среды в этом документе.
  • Промежуточное ПО маршрутизации конечных точек охватывает весь конвейер промежуточного ПО, поэтому нет необходимости явно вызывать UseRouting или UseEndpoints для регистрации маршрутов. UseRouting по-прежнему можно использовать для указания того, где происходит сопоставление маршрутов, но UseRouting не нужно явно вызывать, если маршруты должны сопоставляться в начале потока по промежуточному слою.
  • Конвейер создается до выполнения IStartupFilter, поэтому исключения, вызванные при создании конвейера, не видны цепочке IStartupFilter вызовов.
  • Некоторые средства, такие как миграция EF, используют Program.CreateHostBuilder для доступа к приложению IServiceProvider, чтобы выполнять пользовательскую логику в контексте приложения. Эти средства были обновлены, чтобы использовать новый метод для выполнения пользовательской логики в контексте приложения. Entity Framework Migrations — это пример средства, которое используется Program.CreateHostBuilder таким образом. Мы работаем над тем, чтобы убедиться, что средства обновлены для использования новой модели.
  • В отличие от Startup класса, минимальный хост автоматически не конфигурирует область DI при создании поставщика услуг. Для контекстов, в которых требуется область, необходимо вызвать IServiceScope с помощью IServiceScopeFactory.CreateScope , чтобы создать экземпляр новой области. Дополнительные сведения см. в статье о том, как разрешить службу при запуске приложения.
  • Изменить параметры узла, например имя приложения, среду или корневой каталог содержимого после создания . Подробные инструкции по изменению параметров узла см. в разделе Настройка IHostBuilder или IWebHostBuilder. Следующие выделенные API вызывают исключение:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

// WebHost

try
{
    builder.WebHost.UseContentRoot(Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseEnvironment(Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.ApplicationKey, "ApplicationName2");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.ContentRootKey, Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.EnvironmentKey, Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

// Host
try
{
    builder.Host.UseEnvironment(Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    // TODO: This does not throw
    builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();
  • Класс Startup нельзя использовать из WebApplicationBuilder.Host или WebApplicationBuilder.WebHost. Следующий выделенный код вызывает исключение:

    var builder = WebApplication.CreateBuilder(args);
    
    try
    {
        builder.Host.ConfigureWebHostDefaults(webHostBuilder =>
        {
            webHostBuilder.UseStartup<Startup>();
        });
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        throw;    
    }
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
    var builder = WebApplication.CreateBuilder(args);
    
    try
    {
        builder.WebHost.UseStartup<Startup>();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        throw;    
    }
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
  • Реализация IHostBuilder на WebApplicationBuilder (WebApplicationBuilder.Host) не откладывает выполнение методов ConfigureServices, ConfigureAppConfiguration или ConfigureHostConfiguration. Отказ от откладывания выполнения позволяет коду, использующему WebApplicationBuilder, наблюдать изменения, внесенные в IServiceCollection и IConfiguration. Следующий пример добавляет только Service1 в качестве IService.

    using Microsoft.Extensions.DependencyInjection.Extensions;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Host.ConfigureServices(services =>
    {
        services.TryAddSingleton<IService, Service1>();
    });
    
    builder.Services.TryAddSingleton<IService, Service2>();
    
    var app = builder.Build();
    
    // Displays Service1 only.
    Console.WriteLine(app.Services.GetRequiredService<IService>());
    
    app.Run();
    
    class Service1 : IService
    {
    }
    
    class Service2 : IService
    {
    }
    
    interface IService
    {
    }
    

В приведенном выше коде обратный вызов builder.Host.ConfigureServices выполняется непосредственно, а не откладывается до вызова builder.Build. Это означает, что Service1 добавляется к IServiceCollection до Service2 и в результате Service1 разрешает IService.

Создание библиотек для ASP.NET Core в .NET 6

Существующая экосистема .NET построила расширяемость вокруг IServiceCollection, IHostBuilderи IWebHostBuilder. Эти свойства доступны на WebApplicationBuilder как Services, Host, и WebHost.

WebApplication реализует оба Microsoft.AspNetCore.Builder.IApplicationBuilder и Microsoft.AspNetCore.Routing.IEndpointRouteBuilder.

Мы ожидаем, что авторы библиотек будут продолжать ориентироваться на IHostBuilder, IWebHostBuilder, IApplicationBuilder и IEndpointRouteBuilder при создании компонентов для ASP.NET Core. Это гарантирует, что ваше промежуточное ПО, обработчик маршрутов или другие точки расширяемости продолжают работать в разных моделях размещения.

Часто задаваемые вопросы (FAQ)

  • Является ли новая минимальная модель размещения менее способной?

    Нет. Новая модель размещения функционально эквивалентна 98% сценариям, поддерживаемым как IHostBuilder, так и IWebHostBuilder. Существуют некоторые сложные сценарии, требующие конкретных обходных IHostBuilderрешений, но мы ожидаем, что они будут чрезвычайно редкими.

  • Не рекомендуется ли использовать универсальную модель размещения?

    Нет. Универсальная модель размещения — это альтернативная модель, которая поддерживается бесконечно. Универсальный узел лежит в основе новой модели размещения и по-прежнему является основным способом размещения рабочих приложений.

  • Обязан ли я переходить на новую модель размещения?

    Нет. Новая модель размещения является предпочтительным способом размещения новых приложений с помощью .NET 6 или более поздней версии, но вы не вынуждены изменять макет проекта в существующих приложениях. Это означает, что приложения могут обновляться с .NET 5 до .NET 6, изменив целевую платформу в файле проекта на net5.0net6.0. Дополнительные сведения см. в разделе "Обновление целевой платформы " в этой статье. Однако мы рекомендуем приложениям перейти на новую модель размещения, чтобы воспользоваться новыми функциями, доступными только для новой модели размещения.

  • Нужно ли использовать инструкции верхнего уровня?

    Нет. Новые шаблоны проектов используют инструкции верхнего уровня, но новые API размещения можно использовать в любом приложении .NET 6 для размещения веб-сервера или веб-приложения.

  • Где поместить состояние, которое хранилось в качестве полей в моем Program или Startup классе?

    Настоятельно рекомендуется использовать внедрение зависимостей (DI) для потока состояния в приложениях ASP.NET Core.

    Существует два подхода к хранению состояния за пределами DI:

    • Сохраните состояние в другом классе. При хранении в классе предполагается статическое состояние, к которому можно получить доступ в любом месте приложения.

    • Используйте класс, Program созданный операторами верхнего уровня, для хранения состояния. Использование Program для хранения состояния — это семантический подход:

      var builder = WebApplication.CreateBuilder(args);
      
      ConfigurationValue = builder.Configuration["SomeKey"] ?? "Hello";
      
      var app = builder.Build();
      
      app.MapGet("/", () => ConfigurationValue);
      
      app.Run();
      
      partial class Program
      {
          public static string? ConfigurationValue { get; private set; }
      }
      
  • Что делать, если я использовал пользовательский контейнер внедрения зависимостей?

    Поддерживаются пользовательские контейнеры DI. Пример см. в пользовательском контейнере внедрения зависимостей (DI).

  • WebApplicationFactory и TestServer всё ещё работают?

    Да. WebApplicationFactory<TEntryPoint> — это способ тестирования новой модели размещения. Пример см. в Тест с WebApplicationFactory или TestServer.

Blazor

После выполнения инструкций, приведенных ранее в этой статье, чтобы обновить приложение до .NET 6, получите конкретные функции, следуя ссылкам, приведенным в статье "Новые возможности ASP.NET Core в .NET 6".

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

  • Создайте проект версии 6.0 Blazor из одного из Blazor шаблонов проектов. Дополнительные сведения см. в разделе "Инструменты для ASP.NET Core Blazor".
  • Переместите компоненты и код приложения в приложение 6.0, внося изменения в новые функции .NET 6.

Перенос проектов SPA

Перенос приложений Angular из расширений SPA

См. этот запрос на GitHub

Перенос приложений React из расширений SPA

См. перенос приложений React из расширений Spa в этом вопросе GitHub

Обновление образов Docker

Для приложений с помощью Docker обновите инструкции и скрипты DockerfileFROM. Используйте базовый образ, включающий ASP.NET Core в среде выполнения .NET 6. Рассмотрим следующее docker pull различие между ASP.NET Core в .NET 5 и .NET 6:

- docker pull mcr.microsoft.com/dotnet/aspnet:5.0
+ docker pull mcr.microsoft.com/dotnet/aspnet:6.0

См. статью GitHub о критическом изменении: формат средства ведения журнала консоли по умолчанию — JSON.

Изменения пакета SDK для ASP.NET Core Razor

Теперь Razor компилятор использует новую функцию генераторов источников для создания скомпилированных файлов C# из Razor представлений и страниц проекта. В предыдущих версиях:

  • Компиляция опирается на цели RazorGenerate и RazorCompile для генерации кода. Эти целевые объекты больше не допустимы. В .NET 6 создание кода и компиляция поддерживаются одним вызовом компилятора. RazorComponentGenerateDependsOn по-прежнему поддерживается для указания зависимостей, необходимых перед выполнением сборки.
  • Была создана отдельная Razor сборка, AppName.Views.dllсодержащая скомпилированные типы представлений в приложении. Это поведение устарело, и создается одна сборка AppName.dll , содержащая как типы приложений, так и созданные представления.
  • Приложения в AppName.Views.dll были общедоступными. В .NET 6 типы приложений находятся в AppName.dll, но также internal sealed. Приложения, выполняющие обнаружение типов, не смогут выполнить обнаружение типов в AppName.Views.dll. Ниже показано изменение API:
- public class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
+ internal sealed class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>

Внесите следующие изменения:

  • Следующие свойства больше не применимы к модели одношаговой компиляции.
    • RazorTargetAssemblyAttribute
    • RazorTargetName
    • EnableDefaultRazorTargetAssemblyInfoAttributes
    • UseRazorBuildServer
    • GenerateRazorTargetAssemblyInfo
    • GenerateMvcApplicationPartsAssemblyAttributes

Дополнительные сведения см. в Razor информации о том, что компилятор больше не создает сборку Views.

Шаблоны проектов используют сервер Duende Identity

Шаблоны проектов теперь используют сервер Duende Identity Server.

Это важно

Duende Identity Server — это продукт с открытым исходным кодом с соглашением о взаимной лицензии. Если вы планируете использовать Duende Server в рабочей среде, вам может потребоваться получить коммерческую лицензию от Identity Software и оплатить плату за лицензию. Дополнительные сведения см. в разделе Duende Software: License.

Сведения об использовании Microsoft Azure Active Directory для ASP.NET Core Identityсм. в статье Identity (репозиторий dotnet/aspnetcore GitHub).

DbSet<Key> Добавьте свойство с именем Keys для каждого IdentityDbContext для удовлетворения нового требования из обновленной IPersistedGrantDbContextверсии. Ключи необходимы в рамках контракта с магазинами Duende Identity Server.

public DbSet<Key> Keys { get; set; }

Замечание

Существующие миграции необходимо повторно создать для сервера Duende Identity .

Примеры кода, перенесенные в ASP.NET Core в .NET 6

Примеры кода перенесены на новую минимальную модель размещения в 6.0

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

Ознакомьтесь с приведенными ниже материалами.

Типы ссылок, допускающие значение NULL (NRTs) и статический анализ состояния компилятора .NET

ASP.NET Шаблоны проектов Core используют ссылочные типы, допускающие значение NULL(NRT), а компилятор .NET выполняет статический анализ состояния NULL. Эти функции были выпущены с помощью C# 8 и включены по умолчанию для приложений, созданных с помощью ASP.NET Core в .NET 6 (C# 10) или более поздней версии.

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

Дополнительные сведения о NRTs, свойстве MSBuild Nullable и обновлении приложений (включая #pragma рекомендации), см. в следующих ресурсах документации по C#:

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

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

Изменение имени приложения

В .NET 6 WebApplicationBuilder нормализует корневой путь содержимого, чтобы он оканчивался на DirectorySeparatorChar. Большинство приложений, перенесенных из HostBuilder или WebHostBuilder не имеющих того же имени приложения, так как они не нормализованы. Дополнительные сведения см. в разделе SetApplicationName

Дополнительные ресурсы