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으로 마이그레이션을 참조하세요.

필수 조건

global.json에서 .NET SDK 버전 업데이트

global.json 파일을 사용하여 특정 .NET SDK 버전을 대상으로 지정하는 경우 version 속성을 설치된 .NET 6.0 SDK 버전으로 업데이트합니다. 예시:

{
  "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>

새 호스팅 모델

ASP.NET Core 앱의 새 .NET 6 최소 호스팅 모델에는 파일 하나와 몇 줄의 코드만 필요합니다. 6.0으로 마이그레이션하는 앱은 새 최소 호스팅 모델을 사용할 필요가 없습니다. 자세한 내용은 다음 섹션에서 6.0으로 마이그레이션하는 앱은 새로운 최소 호스팅 모델을 사용할 필요가 없습니다를 참조하세요.

ASP.NET Core 빈 템플릿의 다음 코드는 새로운 최소 호스팅 모델을 사용하여 앱을 만듭니다.

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

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

app.Run();

최소 호스팅 모델:

  • 앱을 만드는 데 필요한 파일 수와 코드 줄이 대폭 줄어듭니다. 코드 4줄과 함께 파일이 하나만 있으면 됩니다.
  • Startup.csProgram.cs를 단일 Program.cs 파일로 통합합니다.
  • 최상위 문을 사용하여 앱에 필요한 코드를 최소화합니다.
  • 전역 using 지시문을 사용하여 필요한 using의 줄 수를 없애거나 최소화합니다.

다음 코드는사용되지 않는 using 문이 제거된 상태로 ASP.NET Core 5 Web App 템플릿(Razor 페이지)의 Startup.csProgram.cs 파일을 표시합니다.

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으로 마이그레이션하는 자세한 예는 이 문서의 뒷부분에 나옵니다.

웹앱 템플릿에 대해 생성되는 기타 파일에 대한 몇 가지 변경 내용은 다음과 같습니다.

  • Index.cshtmlPrivacy.cshtml의 사용되지 않는 using 문이 제거되었습니다.
  • Error.cshtmlRequestIdNRT(Nullable 참조 형식)으로 선언됩니다.
- 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 Core 템플릿 코드에서 "Microsoft": "Warning""Microsoft.AspNetCore": "Warning"로 변경되었습니다. 이 변경에 따라 Microsoft.AspNetCore제외한Microsoft 네임스페이스의 모든 정보 메시지가 로그됩니다. 예를 들어 Microsoft.EntityFrameworkCore는 이제 정보 수준에서 로그됩니다.

새 호스팅 모델에 대한 자세한 내용은 질문과 대답 섹션을 참조하세요. NRT 채택과 .NET 컴파일러 null 상태 분석에 대한 자세한 내용은 NRT(Nullable 참조 형식) 및 .NET 컴파일러 null 상태 정적 분석 섹션을 참조하세요.

6.0 이상을 사용하거나 마이그레이션하는 앱은 새 최소 호스팅 모델을 사용할 필요가 없습니다.

ASP.NET Core 3.1 및 5.0 템플릿에서 사용하는 Startup제네릭 호스트 사용이 완전히 지원됩니다.

새 최소 호스팅 모델에서 시작 사용

ASP.NET Core 3.1 및 5.0 앱은 새 최소 호스팅 모델에서 Startup 코드를 사용할 수 있습니다. 최소 호스팅 모델과 함께 사용하면 Startup 다음과 같은 이점이 있습니다.

  • 클래스를 호출하는 데 숨겨진 리플렉션이 Startup 사용되지 않습니다.
  • 개발자가 호출을 제어하기 때문에 비동기 코드를 작성할 Startup수 있습니다.
  • 코드는 그 인터리브 ConfigureServicesConfigure..을 작성할 수 있습니다.

새 최소 호스팅 모델에서 코드를 사용하는 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();
        });
    }
}

최소 호스팅 모델을 사용하는 경우 엔드포인트 라우팅 미들웨어는 전체 미들웨어 파이프라인을 래핑하므로 경로를 등록하기 위해 UseRouting 또는 UseEndpoints에 대한 명시적 호출이 필요하지 않습니다. UseRouting은 경로 일치가 발생하는 위치를 지정하는 데 계속 사용할 수 있지만 미들웨어 파이프라인의 시작 부분에서 경로가 일치해야 하는 경우 UseRouting을 명시적으로 호출할 필요는 없습니다.

다음 코드에서 UseRoutingUseEndpoints에 대한 호출은 Startup에서 제거됩니다. MapRazorPagesProgram.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.csStartup 클래스의 인스턴스화 및 수명을 제어합니다.
  • Configure 메서드에 삽입된 추가 서비스는 Program 클래스에서 수동으로 확인해야 합니다.

ASP.NET Core 5 및 6 호스팅 모델의 차이점

  • 개발 모드에서 개발자 예외 페이지 미들웨어는 기본적으로 사용하도록 설정되어 있습니다.
  • 앱 이름은 기본적으로 진입점 어셈블리의 이름인 Assembly.GetEntryAssembly().GetName().FullName으로 지정됩니다. 라이브러리에서 WebApplicationBuilder를 사용하는 경우 앱 이름을 라이브러리의 어셈블리로 명시적으로 변경하여 MVC의 애플리케이션 파트 검색이 작동되도록 합니다. 자세한 지침은 이 문서의 콘텐츠 루트, 앱 이름 및 환경 변경을 참조하세요.
  • 엔드포인트 라우팅 미들웨어는 전체 미들웨어 파이프라인을 래핑하므로 경로를 등록하기 위해 UseRouting 또는 UseEndpoints에 대한 명시적 호출이 필요하지 않습니다. UseRouting은 경로 일치가 발생하는 위치를 지정하는 데 계속 사용할 수 있지만 미들웨어 파이프라인의 시작 부분에서 경로가 일치해야 하는 경우 UseRouting을 명시적으로 호출할 필요는 없습니다.
  • 파이프라인IStartupFilter가 실행되기 전에 생성되므로 파이프라인을 빌드하는 동안 발생한 예외는 IStartupFilter 호출 체인에 표시되지 않습니다.
  • EF 마이그레이션과 같은 일부 도구는 앱의 컨텍스트에서 사용자 지정 논리를 실행하기 위해 Program.CreateHostBuilder를 사용하여 앱의 IServiceProvider에 액세스합니다. 이러한 도구는 앱의 컨텍스트에서 사용자 지정 논리를 실행하는 데 새 기술을 사용하도록 업데이트되었습니다. 이런 식으로 Program.CreateHostBuilder를 사용하는 도구로 Entity Framework 마이그레이션이 있습니다. 새 모델을 사용하도록 도구가 업데이트되었는지 확인하고 있습니다.
  • 클래스와 Startup 달리 최소 호스트는 서비스 공급자를 인스턴스화할 때 DI 범위를 자동으로 구성하지 않습니다. 범위가 필요한 컨텍스트의 경우 IServiceScopeFactory.CreateScope사용하여 호출 IServiceScope 하여 새 범위를 인스턴스화해야 합니다. 자세한 내용은 앱 시작 시 서비스를 확인하는 방법을 참조 하세요.
  • WebApplicationBuilder를 만든 후에는 앱 이름, 환경 또는 콘텐츠 루트 같은 호스트 설정을 변경할 수 없습니다. 호스트 설정을 변경하는 방법에 대한 자세한 내용은 IHostBuilder 또는 IWebHostBuilder 사용자 지정을 참조하세요. 다음의 강조 표시된 API는 예외를 throw합니다.
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에서 사용될 수 없습니다. 다음의 강조 표시된 코드는 예외를 throw합니다.

    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(WebApplicationBuilder.Host)의 IHostBuilder 구현은 ConfigureServices, ConfigureAppConfiguration 또는 ConfigureHostConfiguration 메서드의 실행을 지연하지 않습니다. 실행을 지연하지 않으면 WebApplicationBuilder를 사용하는 코드가 IServiceCollectionIConfiguration의 변경 내용을 관찰할 수 있습니다. 다음 예에서는 Service1IService로 추가합니다.

    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가 호출될 때까지 지연되지 않고 인라인으로 호출됩니다. 즉 Service1Service2 전에 IServiceCollection에 추가되고 그 결과로 Service1IService에 대해 확인됩니다.

ASP.NET Core 6용 라이브러리 빌드

기존 .NET 에코시스템이 IServiceCollection, IHostBuilderIWebHostBuilder에 대한 확장성을 구축했습니다. 이러한 속성은 Services, HostWebHostWebApplicationBuilder에서 사용할 수 있습니다.

WebApplicationMicrosoft.AspNetCore.Builder.IApplicationBuilderMicrosoft.AspNetCore.Routing.IEndpointRouteBuilder를 둘 다 구현합니다.

라이브러리 작성자는 ASP.NET Core 특정 구성 요소를 빌드할 때 IHostBuilder, IWebHostBuilder, IApplicationBuilderIEndpointRouteBuilder를 계속 대상으로 지정할 것입니다. 그러면 미들웨어, 경로 처리기 또는 기타 확장 포인트가 여러 호스팅 모델에서 계속 작동합니다.

질문과 대답(FAQ)

  • 새 최소 호스팅 모델은 성능이 약화되었나요?

    아니요. 새 호스팅 모델은 IHostBuilderIWebHostBuilder에서 지원하는 시나리오의 98%에서 동일하게 작동합니다. IHostBuilder에서 특정 해결 방법이 필요한 고급 시나리오가 있지만, 그러한 경우는 극히 드물 것입니다.

  • 일반 호스팅 모델은 이제 사용되지 않나요?

    아니요. 일반 호스팅 모델은 무기한으로 지원되는 대체 모델입니다. 일반 호스트는 새 호스팅 모델을 보강하며 작업자 기반 애플리케이션을 호스트하는 기본 방법입니다.

  • 새 호스팅 모델로 마이그레이션해야 하나요?

    아니요. 새 호스팅 모델은 .NET 6 이상을 사용하여 새 앱을 호스트하기에 좋은 방법이지만 기존 앱에서 프로젝트 레이아웃을 변경하도록 강요되는 것은 아닙니다. 프로젝트 파일의 대상 프레임워크를 net5.0에서 net6.0으로 변경하여 앱을 .NET 5에서 .NET 6으로 업그레이드할 수 있습니다. 자세한 내용은 이 문서의 대상 프레임워크 업데이트 섹션을 참조하세요. 그러나 새 호스팅 모델에만 사용할 수 있는 새로운 기능을 활용하려면 앱을 새 호스팅 모델로 마이그레이션하는 것이 좋습니다.

  • 최상위 문을 사용해야 하나요?

    아니요. 새 프로젝트 템플릿은 모두 최상위 문을 사용하지만, 웹 서버 또는 웹앱을 호스트하기 위해 .NET 6 앱에서 새 호스팅 API를 사용할 수 있습니다.

  • Program 또는 Startup 클래스에 필드로 저장된 상태는 어디에 두나요?

    ASP.NET Core 앱에서 상태를 이동하려면 DI(종속성 주입)를 사용하는 것이 좋습니다.

    다음과 같은 두 가지 방법으로 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(종속성 주입) 컨테이너를 참조하세요.

  • WebApplicationFactoryTestServer는 계속 작동하나요?

    예. WebApplicationFactory<TEntryPoint>는 새 호스팅 모델을 테스트하는 방법입니다. 예제를 보려면 WebApplicationFactory 또는 TestServer로 테스트를 참조하세요.

Blazor

이 문서의 앞부분에 있는 지침에 따라 앱을 6.0으로 업데이트한 후 ASP.NET Core 6.0의 새로운 기능 링크를 따라 특정 기능을 채택합니다.

Blazor 앱의 새 6.0 기능을 모두 채택하려면 다음 프로세스를 따르세요.

  • Blazor 프로젝트 템플릿 중 하나에서 새 6.0 Blazor 프로젝트를 만듭니다. 자세한 내용은 ASP.NET Core Blazor 도구를 참조하세요.
  • 앱의 구성 요소와 코드를 새 6.0 기능을 채택하도록 수정된 6.0 앱으로 이동합니다.

SPA 프로젝트 마이그레이션

SPA 확장에서 Angular 앱 마이그레이션

GitHub 이슈를 참조하세요.

SPA 확장에서 React 앱 마이그레이션

이 GitHub 이슈에서 Spa 확장에서 React 애플리케이션 마이그레이션을 참조하세요.

Docker 이미지 업데이트

Docker를 사용하는 앱의 경우 DockerfileFROM 문과 스크립트를 업데이트합니다. ASP.NET Core 6.0 런타임을 포함하는 기본 이미지를 사용합니다. ASP.NET Core 5.0과 6.0 간에 docker pull 명령 차이를 고려합니다.

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

GitHub 이슈 호환성이 손상되는 변경: 기본 콘솔 로거 형식이 JSON으로 설정됨을 참조하세요.

ASP.NET Core Razor SDK 변경 내용

이제 Razor 컴파일러가 새 소스 생성기 기능을 사용하여 프로젝트의 Razor 뷰와 페이지에서 컴파일된 C# 파일을 생성합니다. 이전 버전에서:

  • 컴파일은 RazorGenerateRazorCompile 대상을 사용하여 생성된 코드를 생성했습니다. 이러한 대상은 더 이상 유효하지 않습니다. .NET 6에서 코드 생성과 컴파일은 모두 컴파일러에 대한 단일 호출로 지원됩니다. RazorComponentGenerateDependsOn은 빌드 실행 전 필요한 종속성을 지원하기 위해 계속 지원됩니다.
  • 애플리케이션의 컴파일된 뷰 형식이 포함된 별도의 Razor 어셈블리 AppName.Views.dll이 생성되었습니다. 이 동작은 더 이상 사용되지 않으며, 앱 형식과 생성된 뷰가 모두 포함되는 단일 어셈블리 AppName.dll이 생성됩니다.
  • AppName.Views.dll의 앱 형식은 퍼블릭이었습니다. .NET 6에서 앱 형식은 AppName.dll에 있지만 internal sealed입니다. 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 컴파일러가 더 이상 뷰 어셈블리를 생성하지 않음을 참조하세요.

프로젝트 템플릿에서 Duende Identity Server 사용

이제 프로젝트 템플릿에서 Duende Identity Server를 사용합니다. 마이그레이션 지침은 IdentityServer4 v4.1을 Duende IdentityServer v5로 업그레이드를 참조하세요.

Important

Duende Identity Server는 상호 라이선스 계약이 있는 오픈 소스 제품입니다. 프로덕션에서 Duende Identity Server를 사용하려는 경우 Duende Software에서 상용 라이선스를 구입하고 라이선스 요금을 지불해야 할 수 있습니다. 자세한 내용은 Duende Software: 라이선스를 참조하세요.

ASP.NET Core Identity에 대해 Microsoft Azure Active Directory를 사용하는 방법을 알아보려면 Identity (dotnet/aspnetcore GitHub 리포지토리)를 참조하세요.

Keys라는 DbSet<Key> 속성을 모든 IdentityDbContext에 추가하여 업데이트된 버전의 IPersistedGrantDbContext의 새 요구 사항을 충족하세요. Duende Identity Server의 스토어와 계약의 일환으로 키가 필요합니다.

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

참고 항목

기존 마이그레이션은 Duende Identity Server에 대해 다시 생성되어야 합니다.

ASP.NET Core 6.0으로 마이그레이션된 코드 샘플

6.0의 새로운 최소 호스팅 모델로 마이그레이션된 코드 샘플

호환성이 손상되는 변경 검토

다음 리소스를 참조하세요.

NRT(Nullable 참조 형식) 및 .NET 컴파일러 null 상태 정적 분석

ASP.NET Core 프로젝트 템플릿에는 NRT(Nullable 참조 형식) 사용과 .NET 컴파일러의 null 상태 정적 분석이 포함됩니다. 이러한 기능은 C# 8에서 릴리스되었으며 ASP.NET Core 6.0(C# 10) 이상에서 생성된 앱에서 기본적으로 사용됩니다.

.NET 컴파일러의 null 상태 정적 분석 경고는 설명서 예제 또는 샘플 앱을 로컬로 업데이트하기 위한 지침으로 사용하거나 무시할 수 있습니다. Null 상태 정적 분석은 앱의 프로젝트 파일에서 Nullabledisable로 설정하여 사용하지 않도록 설정할 수 있으며, .NET에 관해 알아보는 동안 컴파일러 경고가 불필요한 경우 이 기능은 설명서 예제와 샘플 앱에만 권장됩니다. 프로덕션 프로젝트에서는 null 상태 검사를 사용하지 않도록 설정하는 것이 좋습니다.

NRT, MSBuild Nullable 속성, 앱 업데이트(#pragma 지침 포함)에 관한 자세한 내용은 C# 설명서의 다음 리소스를 참조하세요.

ASP.NET Core 모듈(ANCM)

Visual Studio를 설치할 때 ANCM(ASP.NET Core 모듈)이 선택된 구성 요소가 아니거나 이전 버전의 ANCM이 시스템에 설치된 경우, 최신 .NET Core 호스팅 번들 설치 관리자(직접 다운로드)를 다운로드하고 설치 관리자를 실행합니다. 자세한 내용은 호스팅 번들을 참조하세요.

애플리케이션 이름 변경

.NET 6에서는 WebApplicationBuilder가 콘텐츠 루트 경로를 정규화하여 DirectorySeparatorChar로 끝납니다. HostBuilder 또는 WebHostBuilder에서 마이그레이션하는 대부분의 앱은 정규화되지 않으므로 동일한 앱 이름을 갖지 않습니다. 자세한 내용은 SetApplicationName을 참조하세요.

추가 리소스