Переход с ASP.NET Core 5.0 на 6.0

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

Необходимые компоненты

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

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

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

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

Обновите moniker целевой платформы проекта (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 требует только одного файла и нескольких строк кода. Приложения, перенесенные на версию 6.0, не должны использовать новую модель минимального размещения. Дополнительные сведения см. в разделе "Приложения, перенесенные на 6.0", не нужно использовать новую модель минимального размещения в следующем разделе.

Следующий код из пустого шаблона 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 файлы из шаблона веб-приложения ASP.NET Core 5 (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 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 6 показано, как:

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

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

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

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

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

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

Использование Startup и универсальный узел , используемый шаблонами 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 5 и 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();
        });
    }
}

При использовании минимальной модели размещения ПО промежуточного слоя маршрутизации конечных точек упаковывает весь конвейер ПО промежуточного слоя, поэтому нет необходимости явно вызывать UseRoutingUseEndpoints или регистрировать маршруты. 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 5 и 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, чтобы создать экземпляр новой область. Дополнительные сведения см. в статье о том, как разрешить службу при запуске приложения.
  • Изменить параметры узла, например имя приложения, среду или корневой каталог содержимого после создания, WebApplicationBuilderневозможно. Подробные инструкции по изменению параметров узла см. в разделе "Настройка" или IWebHostBuilder"НастройкаIHostBuilder". Следующие выделенные 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();
    
  • WebApplicationBuilder Реализация IHostBuilder в (WebApplicationBuilder.Host), не откладывает выполнение ConfigureServicesConfigureAppConfigurationметодов или 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 6

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

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

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

Вопросы и ответы

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

    № Новая модель размещения функционально эквивалентна 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

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

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

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

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

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

См. эту проблему GitHub

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

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

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

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

- 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 типы приложений находятся только internal sealedв AppName.dll . Приложения, выполняя обнаружение типов, не смогут выполнять обнаружение AppName.Views.dll типов.AppName.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. Рекомендации по миграции см. в разделе IdentityServer4 версии 4.1 с Duende IdentityServer версии 5.

Внимание

Duende Identity Server — это открытый код продукт с соглашением о взаимной лицензии. Если вы планируете использовать Duende Server в рабочей среде, вам может потребоваться получить коммерческую лицензию от Duende 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 6.0

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

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

См. следующие ресурсы.

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

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

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

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

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

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

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

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

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