ASP.NET Core 3.1에서 5.0으로 마이그레이션

이 문서에서는 기존의 ASP.NET Core 3.1 프로젝트를 ASP.NET Core 5.0으로 업데이트하는 방법을 설명합니다. ASP.NET Core 3.1에서 ASP.NET Core 6.0으로 마이그레이션하는 방법에 대한 지침은 ASP.NET Core 3.1에서 6.0으로 마이그레이션을 참조하세요.

필수 조건

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

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

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

대상 프레임워크 업데이트

Blazor WebAssembly 프로젝트를 업데이트하는 경우 Blazor WebAssembly 프로젝트 업데이트 섹션으로 건너뜁니다. 다른 ASP.NET Core 프로젝트 형식의 경우 프로젝트 파일의 TFM(대상 프레임워크 모니커)net5.0으로 업데이트합니다.

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

  <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

</Project>

binobj 폴더 삭제

binobj 폴더를 삭제해야 할 수 있습니다. NuGet 패키지 캐시를 지우려면 dotnet nuget locals --clear all을 실행합니다.

최대 6.0까지의 5.0.1 및 추가 5.x 릴리스에서 Blazor 앱 라우팅 논리에 대한 변경 내용

ASP.NET Core 5.0.1 패치 릴리스에서 경로 우선 순위 계산이 변경되었습니다. 선택적 매개 변수를 통해 catch-all 경로 또는 경로를 정의한 경우 영향을 줄 수 있습니다.

이전 동작

ASP.NET Core 5.0.0 이전의 이전 동작에서는 {*slug}와 같이 우선 순위가 낮은 경로가 /customer/{id}와 같이 우선 순위가 높은 경로보다 먼저 일치합니다.

새 동작

ASP.NET Core 5.0.1 이상의 새 동작은 ASP.NET Core 앱에 정의된 라우팅 동작과 더 밀접하게 일치합니다. 여기서 프레임워크는 각 세그먼트에 대한 경로 우선 순위를 먼저 계산 및 설정하고, 경로 길이만 사용하여 보조 조건으로 동률을 끊습니다.

변경 이유

Blazor 라우팅 시스템이 Blazor 라우팅에서 지원하는 기능의 하위 집합에 대해 ASP.NET Core 라우팅 시스템과 동일한 방식으로 동작하는 것이 목표이므로, 원래 동작은 구현에서 버그로 간주됩니다.

App.razor 파일의 Router 구성 요소에 PreferExactMatches 특성을 추가하여 올바른 동작을 옵트인합니다.

<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">

PreferExactMatches@true로 설정하면 경로 일치에서 와일드카드보다 정확한 일치를 사용합니다.

Important

모든 앱은 명시적으로 PreferExactMatches@true로 설정해야 합니다.

PreferExactMatches@false로 설정하거나 설정하지 않은 상태로 두는 기능은 이전 버전과의 호환성을 위해서만 제공됩니다.

.NET 6이 릴리스되면 라우터는 항상 정확한 일치를 선호하며 PreferExactMatches 옵션을 사용할 수 없습니다.

Blazor WebAssembly 및 Blazor Server 프로젝트 업데이트

이 섹션의 지침은 두 Blazor 호스팅 모델에 모두 적용됩니다. 이 섹션 다음 섹션에서는 호스팅 모델 및 앱 유형과 관련된 추가 지침을 제공합니다. 모든 관련 섹션의 지침을 앱에 적용합니다.

  1. Blazor WebAssembly 앱의 wwwroot/index.html 또는 Blazor Server 앱의 Pages/_Host.cshtml에서 <head> 스타일의 요소에 <link> 요소를 추가합니다. 다음 <link> 요소 href 특성 값에서 자리 표시자 {ASSEMBLY NAME}은 앱의 어셈블리 이름입니다.

    +<link href="{ASSEMBLY NAME}.styles.css" rel="stylesheet" />
    

    독립 실행형 Blazor WebAssembly 또는 Blazor Server 예제:

    +<link href="BlazorSample.styles.css" rel="stylesheet" />
    

    호스팅된 Blazor WebAssembly 솔루션의 Client 프로젝트 예제:

    +<link href="BlazorSample.Client.styles.css" rel="stylesheet" />
    
  2. 구성 요소 가상화Microsoft.AspNetCore.Components.Web.Virtualization에 대한 앱의 _Imports.razor 파일에 새 네임스페이스를 포함합니다. 다음 _Imports.razor 파일은 Blazor 프로젝트 템플릿에서 생성된 앱의 기본 네임스페이스를 보여 줍니다. 자리 표시자 {ASSEMBLY NAME}은 앱의 어셈블리 이름입니다.

    Blazor WebAssembly (_Imports.razor):

    @using System.Net.Http
    @using System.Net.Http.Json
    @using Microsoft.AspNetCore.Components.Forms
    @using Microsoft.AspNetCore.Components.Routing
    @using Microsoft.AspNetCore.Components.Web
    @using Microsoft.AspNetCore.Components.Web.Virtualization
    @using Microsoft.AspNetCore.Components.WebAssembly.Http
    @using Microsoft.JSInterop
    @using {ASSEMBLY NAME}
    @using {ASSEMBLY NAME}.Shared
    

    Blazor Server (_Imports.razor):

    @using System.Net.Http
    @using Microsoft.AspNetCore.Authorization
    @using Microsoft.AspNetCore.Components.Authorization
    @using Microsoft.AspNetCore.Components.Forms
    @using Microsoft.AspNetCore.Components.Routing
    @using Microsoft.AspNetCore.Components.Web
    @using Microsoft.AspNetCore.Components.Web.Virtualization
    @using Microsoft.JSInterop
    @using {ASSEMBLY NAME}
    @using {ASSEMBLY NAME}.Shared
    
  3. MainLayout 구성 요소(Shared/MainLayout.razor)에서 구성 요소의 HTML 태그를 class 특성이 page로 설정된 <div> 요소로 감쌉니다.

    <div class="page">
    
        ...
    
    </div>
    
  4. 다음 파일을 Shared 폴더에 추가합니다.

    MainLayout.razor.css:

    .page {
        position: relative;
        display: flex;
        flex-direction: column;
    }
    
    .main {
        flex: 1;
    }
    
    .sidebar {
        background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
    }
    
    .top-row {
        background-color: #f7f7f7;
        border-bottom: 1px solid #d6d5d5;
        justify-content: flex-end;
        height: 3.5rem;
        display: flex;
        align-items: center;
    }
    
        .top-row ::deep a, .top-row .btn-link {
            white-space: nowrap;
            margin-left: 1.5rem;
        }
    
        .top-row a:first-child {
            overflow: hidden;
            text-overflow: ellipsis;
        }
    
    @media (max-width: 767.98px) {
        .top-row:not(.auth) {
            display: none;
        }
    
        .top-row.auth {
            justify-content: space-between;
        }
    
        .top-row a, .top-row .btn-link {
            margin-left: 0;
        }
    }
    
    @media (min-width: 768px) {
        .page {
            flex-direction: row;
        }
    
        .sidebar {
            width: 250px;
            height: 100vh;
            position: sticky;
            top: 0;
        }
    
        .top-row {
            position: sticky;
            top: 0;
            z-index: 1;
        }
    
        .main > div {
            padding-left: 2rem !important;
            padding-right: 1.5rem !important;
        }
    }
    

    NavMenu.razor.css:

    .navbar-toggler {
        background-color: rgba(255, 255, 255, 0.1);
    }
    
    .top-row {
        height: 3.5rem;
        background-color: rgba(0,0,0,0.4);
    }
    
    .navbar-brand {
        font-size: 1.1rem;
    }
    
    .oi {
        width: 2rem;
        font-size: 1.1rem;
        vertical-align: text-top;
        top: -2px;
    }
    
    .nav-item {
        font-size: 0.9rem;
        padding-bottom: 0.5rem;
    }
    
        .nav-item:first-of-type {
            padding-top: 1rem;
        }
    
        .nav-item:last-of-type {
            padding-bottom: 1rem;
        }
    
        .nav-item ::deep a {
            color: #d7d7d7;
            border-radius: 4px;
            height: 3rem;
            display: flex;
            align-items: center;
            line-height: 3rem;
        }
    
    .nav-item ::deep a.active {
        background-color: rgba(255,255,255,0.25);
        color: white;
    }
    
    .nav-item ::deep a:hover {
        background-color: rgba(255,255,255,0.1);
        color: white;
    }
    
    @media (min-width: 768px) {
        .navbar-toggler {
            display: none;
        }
    
        .collapse {
            /* Never collapse the sidebar for wide screens */
            display: block;
        }
    }
    
  5. Blazor WebAssembly 앱의 최신 기본 wwwroot/css/app.css 파일 또는 Blazor Server 앱의 wwwroot/css/site.css 파일에는 다음 스타일이 포함됩니다. 다음 스타일과 앱에 추가한 스타일을 그대로 두고 추가 스타일을 제거합니다.

    다음 스타일시트에는 기본 스타일만 포함되며 개발자가 추가한 사용자 지정 스타일은 포함되지 않습니다.

    html, body {
        font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    }
    
    a, .btn-link {
        color: #0366d6;
    }
    
    .btn-primary {
        color: #fff;
        background-color: #1b6ec2;
        border-color: #1861ac;
    }
    
    .content {
        padding-top: 1.1rem;
    }
    
    .valid.modified:not([type=checkbox]) {
        outline: 1px solid #26b050;
    }
    
    .invalid {
        outline: 1px solid red;
    }
    
    .validation-message {
        color: red;
    }
    
    #blazor-error-ui {
        background: lightyellow;
        bottom: 0;
        box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
        display: none;
        left: 0;
        padding: 0.6rem 1.25rem 0.7rem 1.25rem;
        position: fixed;
        width: 100%;
        z-index: 1000;
    }
    
    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
    

    참고 항목

    앞의 예제에서는 프로젝트 템플릿에서 @import 제공하는 Blazor Open Iconic 아이콘(open-iconic-bootstrap.css)에 대한 지시문을 표시하지 않습니다. 오픈 아이코닉은 기본 테인에 의해 버려졌습니다.

프로젝트 업데이트 Blazor WebAssembly

이전 Blazor WebAssembly 및 Blazor Server 프로젝트 업데이트 섹션의 지침을 따릅니다.

호스팅된 Blazor 솔루션의 Client 프로젝트를 포함한 Blazor WebAssembly 프로젝트의 경우 프로젝트 파일에 다음 변경 내용을 적용합니다.

  1. Microsoft.NET.Sdk.Web에서 Microsoft.NET.Sdk.BlazorWebAssembly로 SDK를 업데이트합니다.

    - <Project Sdk="Microsoft.NET.Sdk.Web">
    + <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
    

    참고 항목

    이 업데이트는 독립 실행형 Blazor WebAssembly 프로젝트 및 호스팅된 Blazor 솔루션의 Client 프로젝트에만 적용됩니다.

  2. 다음 속성을 업데이트합니다.

    <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
    
      <PropertyGroup>
    -     <TargetFramework>netstandard2.1</TargetFramework>
    -     <RazorLangVersion>3.0</RazorLangVersion>
    +     <TargetFramework>net5.0</TargetFramework>
      </PropertyGroup>
    
  3. Microsoft.AspNetCore.Components.WebAssembly.Build에 대한 패키지 참조를 제거합니다.

    <ItemGroup>
    -    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.1" PrivateAssets="all" />
    
  4. 다른 패키지를 최신 버전으로 업데이트합니다. 최신 버전은 NuGet.org에서 찾을 수 있습니다.

  5. wwwroot/index.html에서 idapp으로 설정된 <div> 요소로 App 구성 요소를 로드하는 요소를 변경합니다.

    -<app>Loading...</app>
    +<div id="app">Loading...</div>
    
  6. Program.Main(Program.cs)에서 # 해시를 추가하여 <app> 요소에 대한 참조를 CSS 선택기로 변경합니다.

    -builder.RootComponents.Add<App>("app");
    +builder.RootComponents.Add<App>("#app");
    
  7. Program.Main(Program.cs)에서 기본 임시 HttpClient 등록을 범위 지정(있는 경우)으로 변경합니다.

    -builder.Services.AddTransient(sp => new HttpClient 
    -    { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
    +builder.Services.AddScoped(sp => new HttpClient 
    +    { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
    
  8. 호스팅된 Blazor 솔루션의 Client 앱의 Program.Main(Program.cs)에서:

    • 필요에 따라 문자열 클라이언트 기본 주소에 대한 builder.HostEnvironment.BaseAddress를 대체합니다.
    • 명명된 임시 클라이언트 팩터리 등록을 범위 지정으로 변경합니다.
    -builder.Services.AddHttpClient("{APP NAMESPACE}.ServerAPI", 
    -    client => client.BaseAddress = new Uri("https://localhost:5001"))
    -    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
    -builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>()
    -    .CreateClient("{APP NAMESPACE}.ServerAPI"));
    +builder.Services.AddHttpClient("{APP NAMESPACE}.ServerAPI", 
    +    client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    +    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
    +builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
    +    .CreateClient("{APP NAMESPACE}.ServerAPI"));
    

    앞의 코드에서 {APP NAMESPACE} 자리 표시자는 앱의 네임스페이스입니다.

Microsoft 계정을 사용하는 독립 실행형 Blazor WebAssembly 앱

이전 Blazor WebAssembly 및 Blazor Server 프로젝트 업데이트Blazor WebAssembly 프로젝트 업데이트 섹션의 지침을 따릅니다.

Azure Portal에 등록된 독립 실행형 Blazor WebAssembly 앱의 경우 Microsoft 계정에 대해 ME-ID(Microsoft Entra ID)를 사용합니다.

  • 앱에는 openidoffline_access 범위가 필요합니다.

    options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
    options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
    
  • Azure Portal 앱 등록 인증 블레이드에서:

    1. 플랫폼 구성을 제거합니다.
    2. 앱의 리디렉션 URI를 통해 단일 페이지 애플리케이션 플랫폼 구성을 추가합니다.
    3. 액세스 토큰ID 토큰에 대한 암시적 권한 부여를 사용하지 않도록 설정합니다.

자세한 내용은 Microsoft 계정을 사용하여 ASP.NET Core Blazor WebAssembly 독립 실행형 앱 보호를 참조하세요.

Microsoft Entra ID(ME-ID)를 사용하는 독립 실행형 Blazor WebAssembly 앱

이전 Blazor WebAssembly 및 Blazor Server 프로젝트 업데이트Blazor WebAssembly 프로젝트 업데이트 섹션의 지침을 따릅니다.

Microsoft Entra ID(ME-ID)를 사용하기 위해 Azure Portal에 등록된 독립 실행형 Blazor WebAssembly 앱의 경우:

  • 앱에는 https://graph.microsoft.com/User.Read 범위가 필요합니다.

    options.ProviderOptions.DefaultAccessTokenScopes
        .Add("https://graph.microsoft.com/User.Read");
    
  • Azure Portal 앱 등록 인증 블레이드에서:

    1. 플랫폼 구성을 제거합니다.
    2. 앱의 리디렉션 URI를 통해 단일 페이지 애플리케이션 플랫폼 구성을 추가합니다.
    3. 액세스 토큰ID 토큰에 대한 암시적 권한 부여를 사용하지 않도록 설정합니다.

자세한 내용은 Microsoft Entra ID를 사용하여 ASP.NET Core Blazor WebAssembly 독립 실행형 앱 보안을 참조하세요.

AAD(Azure Active Directory) B2C를 사용한 독립 실행형 Blazor WebAssembly 앱

이전 Blazor WebAssembly 및 Blazor Server 프로젝트 업데이트Blazor WebAssembly 프로젝트 업데이트 섹션의 지침을 따릅니다.

Azure Portal에 등록된 독립 실행형 Blazor WebAssembly 앱이 AAD(Azure Active Directory) B2C를 사용하는 경우:

  • 앱에는 openidoffline_access 범위가 필요합니다.

    options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
    options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
    
  • Azure Portal 앱 등록 인증 블레이드에서:

    1. 플랫폼 구성을 제거합니다.
    2. 앱의 리디렉션 URI를 통해 단일 페이지 애플리케이션 플랫폼 구성을 추가합니다.
    3. 액세스 토큰ID 토큰에 대한 암시적 권한 부여를 사용하지 않도록 설정합니다.

자세한 내용은 Azure Active Directory B2C를 사용하여 ASP.NET Core Blazor WebAssembly 독립 실행형 앱 보호를 참조하세요.

Microsoft Entra ID(ME-ID) 또는 AAD B2C를 사용하는 호스트된 Blazor WebAssembly 앱

이전 Blazor WebAssembly 및 Blazor Server 프로젝트 업데이트Blazor WebAssembly 프로젝트 업데이트 섹션의 지침을 따릅니다.

사용자 인증을 위해 AAD 또는 AAD B2C를 사용하는 호스팅된 Blazor 솔루션의 Client 앱 등록은 단일 페이지 애플리케이션 Azure Apps 플랫폼 구성을 사용해야 합니다.

Azure Portal Client 앱 등록 인증 블레이드에서:

  1. 플랫폼 구성을 제거합니다.
  2. 앱의 리디렉션 URI를 통해 단일 페이지 애플리케이션 플랫폼 구성을 추가합니다.
  3. 액세스 토큰ID 토큰에 대한 암시적 권한 부여를 사용하지 않도록 설정합니다.

자세한 내용은 다음을 참조하세요.

호스팅된 Blazor 솔루션의 서버 프로젝트 업데이트

이전 섹션의 지침을 따릅니다.

이 문서의 일반적인 지침에 따라 호스팅된 Blazor 솔루션의 Server 프로젝트를 ASP.NET Core 앱으로 업데이트합니다.

Server 또한 MICROSOFT Entra ID(ME-ID) 또는 B2C를 사용하여 클라이언트 Blazor WebAssembly 앱에 사용자를 인증하는 프로젝트는 새 Microsoft Identity v2.0 패키지를 채택해야 합니다.

AAD 경우:

-<PackageReference Include="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="..." />
+<PackageReference Include="Microsoft.Identity.Web" Version="{VERSION}" />
+<PackageReference Include="Microsoft.Identity.Web.UI" Version="{VERSION}" />

AAD B2C의 경우:

-<PackageReference Include="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Version="..." />
+<PackageReference Include="Microsoft.Identity.Web" Version="{VERSION}" />
+<PackageReference Include="Microsoft.Identity.Web.UI" Version="{VERSION}" />

이전 패키지 참조의 경우 NuGet.org에서 {VERSION} 자리 표시자에 대한 패키지 버전을 확인합니다.

참고 항목

호스팅된 Blazor WebAssembly 솔루션에 있는 Server 프로젝트의 SDK는 Microsoft.NET.Sdk.Web으로 유지됩니다.

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

자세한 내용은 다음을 참조하세요.

솔루션 정리 및 다시 빌드

앱 또는 솔루션을 .NET 5로 마이그레이션한 후 앱 또는 솔루션을 정리하고 다시 빌드합니다. 새 패키지 참조와 캐시된 패키지 간에 패키지 비호환성이 있는 경우:

  1. 명령 셸에서 다음 dotnet nuget locals 명령을 실행하여 NuGet 패키지 캐시를 정리합니다.

    dotnet nuget locals --clear all
    
  2. 앱 또는 솔루션을 정리하고 다시 빌드합니다.

문제 해결

앱에 적용되는 Blazor WebAssembly 보안 항목의 마지막에 있는 문제 해결 지침을 따릅니다.

독립 실행형 Blazor WebAssembly 앱:

호스트된 Blazor WebAssembly 앱:

Microsoft Entra ID(ME-ID)에 대한 권한 없는 클라이언트

인증에 AAD를 사용하는 Blazor WebAssembly 앱을 업그레이드한 후 사용자가 AAD로 로그인한 후 앱에 대한 로그인 콜백에서 다음 오류가 발생할 수 있습니다.

info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 권한 부여에 실패했습니다. 이러한 요구 사항이 충족되지 않았습니다. DenyAnonymousAuthorizationRequirement: 인증된 사용자가 필요합니다.

AAD에서 로그인 콜백 오류:

  • 오류: unauthorized_client
  • 설명: AADB2C90058: The provided application is not configured to allow public clients.

오류를 해결하려면:

  1. Azure Portal에서 앱의 매니페스트에 액세스합니다.
  2. allowPublicClient 특성을 null 또는 true로 설정합니다.

Blazor PWA(프로그레시브 웹 애플리케이션) 업데이트

PWA 앱의 프로젝트 파일에 다음 항목을 추가합니다.

<ItemGroup>
  <ServiceWorker Include="wwwroot\service-worker.js" 
    PublishedContent="wwwroot\service-worker.published.js" />
</ItemGroup>

프로젝트의 wwwroot/index.html(Blazor WebAssembly) 또는 Pages/_Host.cshtml(Blazor Server)에 이전 5.0 미리 보기 릴리스의 scoped.styles.css에 대한 스타일시트 <link> 요소가 포함된 경우 <link> 태그를 제거합니다.

-<link href="_framework/scoped.styles.css/" rel="stylesheet" />

RCL(Razor 클래스 라이브러리) 업데이트

ASP.NET Core 5.0의 일부로 도입된 새로운 API 또는 기능을 활용하도록 RCL(Razor 클래스 라이브러리)을 마이그레이션합니다.

구성 요소를 대상으로 하는 RCL을 업데이트하려면 다음을 수행합니다.

  1. 프로젝트 파일에서 다음 속성을 업데이트합니다.

    <Project Sdk="Microsoft.NET.Sdk.Razor">
    
      <PropertyGroup>
    -     <TargetFramework>netstandard2.0</TargetFramework>
    -     <RazorLangVersion>3.0</RazorLangVersion>
    +     <TargetFramework>net5.0</TargetFramework>
      </PropertyGroup>
    
  2. 다른 패키지를 최신 버전으로 업데이트합니다. 최신 버전은 NuGet.org에서 찾을 수 있습니다.

MVC를 대상으로 하는 RCL을 업데이트하려면 프로젝트 파일에서 다음 속성을 업데이트합니다.

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

  <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
    <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
  </PropertyGroup>

패키지 참조 업데이트

프로젝트 파일에서 각 Microsoft.AspNetCore.*, Microsoft.EntityFrameworkCore.*, Microsoft.Extensions.*System.Net.Http.Json 패키지 참조의 Version 특성을 5.0.0 이상으로 업데이트합니다. 예시:

<ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.1.6" />
-    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.6">
-    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="3.1.6" />
-    <PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
+    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.0" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0">
+    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0" />
+    <PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
</ItemGroup>

Docker 이미지 업데이트

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

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

제품 이름에서 “.NET”으로 이동하는 과정의 일환으로 Docker 이미지는 mcr.microsoft.com/dotnet/core 리포지토리에서 mcr.microsoft.com/dotnet으로 이동되었습니다. 자세한 내용은 dotnet/dotnet-docker#1939를 참조하세요.

ASP.NET Core MVC 및 Razor Pages의 모델 바인딩 변경 내용

DateTime 값은 UTC 시간으로 모델 바인딩됩니다.

ASP.NET Core 3.1 이전에서 DateTime 값은 현지 시간으로 모델 바인딩되었으며, 여기서 시간대는 서버에 의해 결정되었습니다. 입력 형식 지정(JSON)에서 바인딩된 DateTime 값과 DateTimeOffset 값은 UTC 시간대로 바인딩되었습니다.

ASP.NET Core 5.0 이상에서는 모델 바인딩이 DateTime 값을 UTC 시간대와 일관되게 바인딩합니다.

이전 동작을 유지해야 하는 경우 Startup.ConfigureServices에서 DateTimeModelBinderProvider를 제거합니다.

services.AddControllersWithViews(options => 
    options.ModelBinderProviders.RemoveType<DateTimeModelBinderProvider>());

ComplexObjectModelBinderProvider \ ComplexObjectModelBinder의 ComplexTypeModelBinderProvider \ ComplexTypeModelBinder 대체

C# 9 레코드 형식의 모델 바인딩을 위한 지원을 추가하기 위해 ComplexTypeModelBinderProvider는 다음과 같습니다.

  • 사용되지 않음으로 주석이 추가되었습니다.
  • 더 이상 기본적으로 등록되지 않습니다.

ModelBinderProviders 컬렉션에서 ComplexTypeModelBinderProvider의 존재에 의존하는 앱은 새 바인더 공급자를 참조해야 합니다.

- var complexModelBinderProvider = options.ModelBinderProviders.OfType<ComplexTypeModelBinderProvider>();
+ var complexModelBinderProvider = options.ModelBinderProviders.OfType<ComplexObjectModelBinderProvider>();

UseDatabaseErrorPage 사용되지 않음

개별 사용자 계정에 대한 옵션을 포함하는 ASP.NET Core 3.1 템플릿은 UseDatabaseErrorPage에 대한 호출을 생성합니다. UseDatabaseErrorPage는 이제 사용되지 않으며 다음 코드와 같이 AddDatabaseDeveloperPageExceptionFilterUseMigrationsEndPoint의 조합으로 대체되어야 합니다.

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

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

자세한 내용은 GitHub 이슈를 참조하세요.

ASP.NET Core 모듈(ANCM)

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

일부 NuGet 패키지에 영향을 주는 패키지 참조 변경 내용

Migrating dotnet/extensions content to dotnet/runtime and dotnet/aspnetcore (aspnet/Announcements #411)에 설명된 대로 dotnet/extensions 리포지토리에서 dotnet/runtime으로 일부 Microsoft.Extensions.* NuGet 패키지를 마이그레이션하면 패키징 변경 내용이 마이그레이션된 일부 패키지에 적용됩니다. 이러한 변경으로 인해 .NET API에 대한 네임스페이스가 변경되는 경우가 많습니다.

5.0으로 마이그레이션할 때 앱 네임스페이스 변경에 대한 API를 추가로 조사하려면 .NET API 브라우저를 사용합니다.

Microsoft.Identity.Web을 마이그레이션합니다

다음 위키 페이지에서는 ASP.NET Core 3.1 ~ 5.0에서 Microsoft.Identity.Web을 마이그레이션하는 방법을 설명합니다.

다음 자습서에서는 마이그레이션에 대해서도 설명합니다.

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

.NET Core 3.1에서 .NET 5.0으로의 주요 변경 사항의 경우 버전 3.1에서 5.0으로 마이그레이션 시 주요 변경 사항을 참조하세요. ASP.NET Core 및 Entity Framework Core도 목록에 포함됩니다.