ASP.NET Core 호스트 및 배포 Blazor

참고 항목

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

이 문서에서는 Blazor 앱을 호스트하고 배포하는 방법을 설명합니다.

앱 게시

앱은 릴리스 구성으로 배포하기 위해 게시됩니다.

참고 항목

Server 프로젝트에서 호스트된 Blazor WebAssembly솔루션을 게시합니다.

  1. 빌드 메뉴에서 게시 {APPLICATION} 명령을 선택합니다. 여기서 {APPLICATION} 자리 표시자는 앱의 이름입니다.
  2. publish target을 선택합니다. 로컬로 게시하려면 폴더를 선택합니다.
  3. 폴더 선택 필드에서 기본 위치를 그대로 사용하거나 다른 위치를 지정합니다. Publish 단추를 선택합니다.

앱을 게시하면 배포할 자산을 만들기 전에 프로젝트 종속성의 복원과 프로젝트의 빌드가 트리거됩니다. 빌드 프로세스의 일부로 앱 다운로드 크기와 로드 시간을 줄이기 위해 사용하지 않는 메서드와 어셈블리를 제거합니다.

게시 위치:

  • Blazor 웹앱: 기본적으로 앱은 폴더에 /bin/Release/{TARGET FRAMEWORK}/publish 게시됩니다. 호스트에 publish 폴더의 콘텐츠를 배포합니다.
  • Blazor WebAssembly: 기본적으로 앱은 폴더에 bin\Release\net8.0\browser-wasm\publish\ 게시됩니다. 앱을 정적 사이트로 배포하려면 wwwroot 폴더의 내용을 정적 사이트 호스트에 복사합니다.
  • Blazor Server: 기본적으로 앱은 폴더에 /bin/Release/{TARGET FRAMEWORK}/publish 게시됩니다. 호스트에 publish 폴더의 콘텐츠를 배포합니다.
  • Blazor WebAssembly
    • 독립 실행형: 기본적으로 앱은 앱을 게시 /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot 하는 데 사용되는 SDK 버전에 따라 또는 bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish 폴더에 게시됩니다. 앱을 정적 사이트로 배포하려면 wwwroot 폴더의 내용을 정적 사이트 호스트에 복사합니다.
    • 호스트됨: 클라이언트 앱은 클라이언트 Blazor WebAssembly 앱의 다른 정적 웹 자산과 함께 서버 앱의 폴더에 게시 /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot 됩니다. 호스트에 publish 폴더의 콘텐츠를 배포합니다.

{TARGET FRAMEWORK} 이전 경로의 대상 프레임워크(예: net8.0)입니다.

IIS

IIS에서 Blazor 앱을 호스트하려면 다음 리소스를 참조하세요.

Blazor 앱을 포함하여 ASP.NET Core 앱 간에 앱 풀을 공유하는 것은 지원되지 않습니다. IIS를 사용하여 호스트할 때 앱당 하나의 앱 풀을 사용하고 여러 앱을 호스트하기 위해 IIS의 가상 디렉터리를 사용하지 않도록 합니다.

호스팅된 Blazor WebAssembly 솔루션이라고도 하는 ASP.NET Core 앱에 의해 호스팅된 하나 이상의 Blazor WebAssembly 앱은 하나의 앱 풀에 대해 지원됩니다. 그러나 호스트된 여러 Blazor WebAssembly 솔루션이나 하위 앱 호스팅 시나리오에 단일 앱 풀을 할당하는 것을 권장하거나 지원하지 않습니다.

솔루션에 대한 자세한 내용은 ASP.NET Core Blazor용 도구를 참조하세요.

앱 기본 경로

앱 기본 경로는 앱의 루트 URL 경로입니다. 앱에서 Blazor 성공적으로 라우팅하려면 기본 앱 기본 /경로에 없는 루트 URL 경로에 대한 프레임워크 구성이 필요합니다.

다음 ASP.NET Core 앱 및 Blazor 하위 앱을 고려하세요.

  • ASP.NET Core 앱의 이름은 MyApp다음과 같습니다.
    • 앱의 실제 위치는 d:/MyApp입니다.
    • 요청은 https://www.contoso.com/{MYAPP RESOURCE}에서 수신됩니다.
  • Blazor 이름이 지정된 CoolApp 앱은 다음의 MyApp하위 앱입니다.
    • 하위 앱의 실제 위치는 d:/MyApp/CoolApp입니다.
    • 요청은 https://www.contoso.com/CoolApp/{COOLAPP RESOURCE}에서 수신됩니다.

CoolApp에 대한 추가 구성을 지정하지 않으면 이 시나리오의 하위 앱은 서버에 상주하는 위치에 대해 알지 못합니다. 예를 들어 앱은 상대 URL 경로 /CoolApp/에 상주한다는 사실을 모르는 상태에서는 해당 리소스의 올바른 상대 URL을 생성할 수 없습니다. 이 시나리오는 앱이 루트 URL 경로에서 호스트되지 않는 경우 다양한 호스팅 및 역방향 프록시 시나리오에도 적용됩니다.

배경

앵커 태그의 대상(href)은 다음 두 엔드포인트 중 하나를 사용하여 구성할 수 있습니다.

  • 스키마를 포함하는 절대 위치(생략된 경우 페이지 구성표의 기본값), 호스트, 포트 및 경로 또는 슬래시(/)와 경로가 뒤따릅니다.

    예: https://example.com/a/b/c 또는 /a/b/c

  • 경로만 포함하고 슬래시(/)로 시작하지 않는 상대 위치입니다. 지정된 경우 현재 문서 URL 또는 <base> 태그 값을 기준으로 확인됩니다.

    예: a/b/c

구성된 앱 기본 경로에 후행 슬래시(/)가 있는 것은 앱의 URL에 대한 기본 경로를 계산하는 데 중요합니다. 예를 들어 https://example.com/a 후행 슬래시에는 기본 경로 https://example.com/가 있는 반면 https://example.com/a/ 에 기본 경로 https://example.com/a는 다음과 같습니다.

ASP.NET Core 앱과 관련된 Blazor 세 가지 링크 원본이 있습니다.

  • 구성 요소(.razor)의 Razor URL은 일반적으로 상대적입니다.
  • 스크립트(예: Blazor 스크립트)blazor.*.js의 URL은 문서를 기준으로 합니다.
  • 파일()Blazor Server에 _Host.cshtml 수동으로 작성된 URL로, 다른 문서 내에서 렌더링하는 경우 항상 절대적이어야 합니다.
  • 구성 요소(.razor)의 Razor URL은 일반적으로 상대적입니다.
  • 스크립트(예: Blazor 스크립트)blazor.*.js의 URL은 문서를 기준으로 합니다.

다른 문서에서 앱을 렌더링하는 Blazor 경우(예 /Admin/B/C//Admin/D/E/: ) 앱 기본 경로를 고려해야 합니다. 또는 앱이 각 문서에서 렌더링되고 리소스가 잘못된 URL에서 인출될 때 기본 경로가 다릅니다.

상대 링크를 올바르게 해결하는 문제를 처리하는 두 가지 방법이 있습니다.

  • 루트로 렌더링된 문서를 사용하여 리소스를 동적으로 매핑합니다.
  • 문서의 일관된 기본 경로를 설정하고 해당 기본 경로 아래에 리소스를 매핑합니다.

첫 번째 옵션은 더 복잡하며 각 문서에 대해 탐색을 다르게 만들기 때문에 가장 일반적인 방법은 아닙니다. 페이지를 /Something/Else렌더링하는 다음 예제를 고려하세요.

  • 아래에 /Admin/B/C/렌더링된 페이지는 .의 /Admin/B/C/Something/Else경로로 렌더링됩니다.
  • 아래에 /Admin/D/E/렌더링된 페이지는 같은 경로/Admin/B/C/Something/Else로 렌더링됩니다.

첫 번째 방법에서 라우팅은 런타임에 요청 라우팅 방법을 결정하는 완전히 동적 솔루션을 구현하기 위한 기초가 될 수 있는 라우팅 제안과 MatcherPolicy함께 제공됩니다IDynamicEndpointMetadata.

일반적인 방식인 두 번째 옵션의 경우 앱은 문서의 기본 경로를 설정하고 서버 엔드포인트를 기본 경로에 매핑합니다. 다음 지침에서는 이 방법을 채택합니다.

서버 쪽 Blazor

SignalR 파일에 경로를 전달하여 서버 쪽 Blazor 앱의 허브를 MapBlazorHubProgram 매핑합니다.

app.MapBlazorHub("base/path");

사용 MapBlazorHub 의 이점은 구체적인 경로뿐만 아니라 패턴을 "{tenant}" 매핑할 수 있다는 것입니다.

분기된 미들웨어 파이프라인이 SignalR 있는 가상 폴더에 앱이 있을 때 허브를 매핑할 수도 있습니다. 다음 예제에서 요청은 /base/path/ 's SignalR 허브'에 의해 Blazor처리됩니다.

app.Map("/base/path/", subapp => {
    subapp.UsePathBase("/base/path/");
    subapp.UseRouting();
    subapp.UseEndpoints(endpoints => endpoints.MapBlazorHub());
});

<base> 앱 기본 경로 구성 섹션의 지침에 따라 태그를 구성합니다.

호스트 Blazor WebAssembly

앱이 호스트 Blazor WebAssembly 된 앱인 경우:

  • 프로젝트의 에서:Program.csServer>
    • 경로 UseBlazorFrameworkFiles (예: app.UseBlazorFrameworkFiles("/base/path");)를 조정합니다.
    • 호출을 구성합니다 UseStaticFiles (예: app.UseStaticFiles("/base/path");).
  • 프로젝트에서 다음을 수행 Client 합니다.
    • 정적 웹 자산(예<StaticWebAssetBasePath>base/path</StaticWebAssetBasePath> : )을 제공하는 경로와 일치하도록 프로젝트 파일에서 구성 <StaticWebAssetBasePath> 합니다.
    • <base> 앱 기본 경로 구성 섹션의 지침에 따라 태그를 구성합니다.

호스트 Blazor WebAssembly 된 솔루션에서 여러 Blazor WebAssembly 앱을 호스팅하는 예제는 여러 호스트된 ASP.NET Core Blazor WebAssembly 앱을 참조하세요. 여기서는 여러 Blazor WebAssembly 클라이언트 앱의 할 일기본/포트 호스팅 및 하위 경로 호스팅에 대한 방법을 설명합니다.

독립 실행형 Blazor WebAssembly

독립 실행형 Blazor WebAssembly 앱에서는 앱 기본 경로 구성 섹션의 <base> 지침에 따라 태그만 구성됩니다.

앱 기본 경로 구성

앱의 기본 경로에 대한 Blazor 구성을 제공하려면 상대 루트 경로 https://www.contoso.com/CoolApp/라고도 하는 앱 기본 경로를 설정합니다.

앱 기본 경로를 구성하여 루트 디렉터리에 없는 구성 요소는 앱의 루트 경로를 기준으로 URL을 생성할 수 있습니다. 디렉터리 구조의 다른 수준에 있는 구성 요소는 앱 전체의 위치에서 다른 리소스에 대한 링크를 만들 수 있습니다. 또한 링크의 href 대상이 앱 기본 경로 URI 공간 내에 있는 경우 선택한 하이퍼링크를 가로채는 데 앱 기본 경로가 사용됩니다. Router 구성 요소는 내부 탐색을 처리합니다.

많은 호스팅 시나리오에서 앱에 대한 상대 URL 경로는 앱의 루트입니다. 이러한 기본 경우 앱의 상대 URL 기본 경로는 콘텐츠에서와 같이 <base href="/" /> 구성됩니다/.<head>

많은 호스팅 시나리오에서 앱에 대한 상대 URL 경로는 앱의 루트입니다. 이러한 기본 사례에서 앱의 상대 URL 기본 경로는 콘텐츠에서 <head> 다음과 같습니다.

  • Blazor Server: ~/<base href="~/" />로 구성됩니다.
  • Blazor WebAssembly: /<base href="/" />로 구성됩니다.

참고 항목

GitHub Pages 및 IIS 하위 앱과 같은 일부 호스팅 시나리오에서는 앱 기본 경로를 앱의 서버 상대 URL 경로로 설정해야 합니다.

  • 서버 쪽 Blazor 앱에서 다음 방법 중 하나를 사용합니다.

    • 옵션 1: <base> 태그를 사용하여 앱의 기본 경로(<head> 컨텐츠의 위치)를 설정합니다.

      <base href="/CoolApp/">
      

      후행 슬래시가 필요합니다.

    • 옵션 2: 앱의 요청 처리 파이프라인(Program.cs)에서 WebApplicationBuilder이 (builder.Build())를 빌드한 직후 UsePathBase먼저 호출하여 요청 경로와 상호 작용하는 다음 미들웨어에 대한 기본 경로를 구성합니다.

      app.UsePathBase("/CoolApp");
      

      Blazor Server 앱을 로컬로 실행하려는 경우에도 UsePathBase 호출이 권장됩니다. 예를 들어 Properties/launchSettings.json에 시작 URL을 제공합니다.

      "launchUrl": "https://localhost:{PORT}/CoolApp",
      

      앞의 예제에서 {PORT} 자리 표시자는 applicationUrl 구성 경로의 보안 포트와 일치하는 포트입니다. 다음 예제에서는 7279 포트에서 앱의 전체 시작 프로필을 보여 줍니다.

      "BlazorSample": {
        "commandName": "Project",
        "dotnetRunMessages": true,
        "launchBrowser": true,
        "applicationUrl": "https://localhost:7279;http://localhost:5279",
        "launchUrl": "https://localhost:7279/CoolApp",
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
      }
      

      launchSettings.json 파일의 자세한 내용은 ASP.NET Core에서 여러 환경 사용을 참조하세요. Blazor 앱 기본 경로 및 호스팅에 대한 자세한 내용은 <base href="/" /> 또는 Blazor MVC 통합에 대한 기본 태그 대체(dotnet/aspnetcore #43191)를 참조하세요.

  • 독립 실행형 Blazor WebAssembly (wwwroot/index.html):

    <base href="/CoolApp/">
    

    후행 슬래시가 필요합니다.

  • Hosted Blazor WebAssembly (Client project, wwwroot/index.html):

    <base href="/CoolApp/">
    

    후행 슬래시가 필요합니다.

    Server 프로젝트에 있는 앱의 요청 처리 파이프라인(Program.cs)에서 WebApplicationBuilderbuilder.Build()를 빌드한 직후 UsePathBase먼저 호출하여 요청 경로와 상호 작용하는 다음 미들웨어에 대한 기본 경로를 구성합니다.

    app.UsePathBase("/CoolApp");
    

참고 항목

라우팅 미들웨어가 경로를 일치하기 전에 수정된 경로를 관찰할 수 있도록 사용(ASP.NET Core 5.0에서 6.0으로 마이그레이션 참조) app.UseRouting 을 호출 WebApplicationUsePathBase 해야 합니다. 그렇지 않은 경우 미들웨어 순서 지정라우팅 문서에서 설명하는 것과 같이 UsePathBase에서 경로를 다시 작성하기 전에 경로가 일치합니다.

앱 전체의 링크에 슬래시를 접두사로 추가하지 마세요. 경로 세그먼트 구분 기호를 사용하지 않거나 점 슬래시(./) 상대 경로 표기법을 사용하지 마세요.

  • 잘못된 예: <a href="/account">
  • 맞는: <a href="account">
  • 맞는: <a href="./account">

HttpClient 서비스를 사용하는 Blazor WebAssembly 웹 API 요청에서 JSON 헬퍼(HttpClientJsonExtensions) URL 앞에 슬래시(/)를 접두사로 추가하지 않는지 확인합니다.

  • 잘못된 예: var rsp = await client.GetFromJsonAsync("/api/Account");
  • 맞는: var rsp = await client.GetFromJsonAsync("api/Account");

탐색 관리자 상대 링크 앞에 슬래시를 접두사로 추가하지 않습니다. 경로 세그먼트 구분 기호를 사용하지 않거나 점 슬래시(./) 상대 경로 표기법을 사용하지 마세요(NavigationNavigationManager으로 삽입됩니다).

  • 잘못된 예: Navigation.NavigateTo("/other");
  • 맞는: Navigation.NavigateTo("other");
  • 맞는: Navigation.NavigateTo("./other");

Azure/IIS 호스팅을 위한 일반적인 구성에서는 일반적으로 추가 구성이 필요하지 않습니다. 일부 비 IIS 호스팅 및 역방향 프록시 호스팅 시나리오에서는 추가 정적 파일 미들웨어 구성이 필요할 수 있습니다.

  • 정적 파일을 올바르게 제공하려면(예: app.UseStaticFiles("/CoolApp");).
  • 스크립트를 Blazor 제공하려면(_framework/blazor.*.js). 자세한 내용은 ASP.NET Core Blazor 정적 파일을 참조하세요.

루트가 아닌 Blazor WebAssembly 상대 URL 경로(예<base href="/CoolApp/">: )가 있는 앱의 경우 로컬로 실행할 때 앱이 해당 리소스를 찾지 못합니다. 로컬 개발 및 시험 중에 이 문제를 해결하려면 런타임에 <base> 태그의 href 값과 일치하는 기본 경로 인수를 제공할 수 있습니다. 후행 슬래시를 포함하지 않습니다. 앱을 로컬로 실행하는 경우 경로 기본 인수를 전달하려면 --pathbase 옵션을 통해 앱의 디렉터리에서 dotnet run 명령을 실행합니다.

dotnet run --pathbase=/{RELATIVE URL PATH (no trailing slash)}

/CoolApp/의 상대 URL 경로를 사용하는 Blazor WebAssembly 앱의 경우(<base href="/CoolApp/">) 명령은 다음과 같습니다.

dotnet run --pathbase=/CoolApp

dotnet run을 사용하여 수동으로 지정하는 대신 자동으로 pathbase를 지정하도록 앱의 시작 프로필을 구성하려면 Properties/launchSettings.json에서 commandLineArgs속성을 설정합니다. 다음은 시작 URL(launchUrl)도 구성합니다.

"commandLineArgs": "--pathbase=/{RELATIVE URL PATH (no trailing slash)}",
"launchUrl": "{RELATIVE URL PATH (no trailing slash)}",

CoolApp을 예로 사용:

"commandLineArgs": "--pathbase=/CoolApp",
"launchUrl": "CoolApp",

dotnet run--pathbase 옵션과 사용하거나 기본 경로를 설정하는 시작 프로필 구성을 사용하면 Blazor WebAssembly 앱이 http://localhost:port/CoolApp에서 로컬로 응답합니다.

launchSettings.json 파일의 자세한 내용은 ASP.NET Core에서 여러 환경 사용을 참조하세요. Blazor 앱 기본 경로 및 호스팅에 대한 자세한 내용은 <base href="/" /> 또는 Blazor MVC 통합에 대한 기본 태그 대체(dotnet/aspnetcore #43191)를 참조하세요.

구성에서 앱 기본 경로 가져오기

다음 지침에서는 다양한 환경에 대한 <base> 앱 설정 파일에서 태그의 경로를 가져오는 방법을 설명합니다.

앱에 앱 설정 파일을 추가합니다. 다음 예제는 환경(appsettings.Staging.json)에 대한 Staging 것입니다.

{
  "AppBasePath": "staging/"
}

서버 쪽 Blazor 앱에서 콘텐츠의 구성 <head> 에서 기본 경로를 로드합니다.

@inject IConfiguration Config

...

<head>
    ...
    <base href="/@(Config.GetValue<string>("AppBasePath"))" />
    ...
</head>

또는 서버 쪽 앱은 에 대한 UsePathBase구성에서 값을 가져올 수 있습니다. 다음 코드를 빌드builder.Build()된 직후 WebApplicationBuilder 앱의 요청 처리 파이프라인(Program.cs)에 먼저 배치합니다. 다음 예제에서는 구성 키를 AppBasePath사용합니다.

app.UsePathBase($"/{app.Configuration.GetValue<string>("AppBasePath")}");

클라이언트 쪽 Blazor WebAssembly 앱에서:

  • 다음 <base> 에서 태그를 제거합니다.wwwroot/index.html

    - <base href="..." />
    
  • 구성 요소의 구성 요소를 App 통해 HeadContent 앱 기본 경로를 제공합니다(App.razor).

    @inject IConfiguration Config
    
    ...
    
    <HeadContent>
        <base href="/@(Config.GetValue<string>("AppBasePath"))" />
    </HeadContent>
    

예를 들어 비 스테이징 환경에서 로드할 구성 값이 없으면 위의 href 루트 경로 /가 확인됩니다.

이 섹션의 예제에서는 앱 설정에서 앱 기본 경로를 제공하는 데 중점을 두지만 경로를 읽 IConfiguration 는 방법은 모든 구성 공급자에 유효합니다. 자세한 내용은 다음 리소스를 참조하세요.

Blazor ServerMapFallbackToPage 구성

이 섹션은 앱에 Blazor Server 만 적용됩니다. MapFallbackToPage는 Web Apps 및 Blazor WebAssembly 앱에서 Blazor 지원되지 않습니다.

앱에 사용자 지정 리소스와 Razor 구성 요소가 포함된 별도의 영역이 필요한 시나리오의 경우:

  • 앱의 Pages 폴더 내에 리소스를 보관할 폴더를 만듭니다. 예를 들어 앱의 관리자 섹션이 Admin(Pages/Admin)이라는 새 폴더에 만들어집니다.

  • 영역의 루트 페이지(_Host.cshtml)를 만듭니다. 예를 들어 앱의 주 루트 페이지(Pages/_Host.cshtml)에서 Pages/Admin/_Host.cshtml 파일을 만듭니다. Admin _Host 페이지에 @page 지시문을 제공하지 마세요.

  • 영역 폴더에 레이아웃을 추가합니다(예: Pages/Admin/_Layout.razor). 별도 영역의 레이아웃에서 영역의 폴더와 일치하도록 <base> 태그 href를 설정합니다(예: <base href="/Admin/" />). 데모용으로 페이지의 정적 리소스에 ~/를 추가합니다. 예시:

    • ~/css/bootstrap/bootstrap.min.css
    • ~/css/site.css
    • ~/BlazorSample.styles.css(예제 앱의 네임스페이스는 BlazorSample임)
    • ~/_framework/blazor.server.js(Blazor 스크립트)
  • 영역에 고유한 정적 자산 폴더가 있어야 하는 경우 폴더를 추가하고 Program.cs의 정적 파일 미들웨어로 위치를 지정합니다(예: app.UseStaticFiles("/Admin/wwwroot")).

  • Razor 구성 요소가 영역의 폴더에 추가됩니다. 최소한, 영역에 대한 올바른 @page 지시문을 사용하여 Index 구성 요소를 영역 폴더에 추가합니다. 예를 들어 앱의 기본 Pages/Index.razor 파일을 기반으로 Pages/Admin/Index.razor 파일을 추가합니다. 파일 맨 위에 경로 템플릿으로 Admin 영역을 나타냅니다(@page "/admin"). 필요에 따라 추가 구성 요소를 추가합니다. 예를 들어 @page 지시문과 함께 Pages/Admin/Component1.razor, @page "/admin/component1의 경로 템플릿을 추가합니다.

  • Program.cs에서 _Host 페이지의 대체 루트 페이지 경로 바로 앞에 영역의 요청 경로에 대한 MapFallbackToPage를 호출합니다.

    ...
    app.UseRouting();
    
    app.MapBlazorHub();
    app.MapFallbackToPage("~/Admin/{*clientroutes:nonfile}", "/Admin/_Host");
    app.MapFallbackToPage("/_Host");
    
    app.Run();
    

여러 Blazor WebAssembly 앱 호스트

호스트된 Blazor솔루션에서 여러 Blazor WebAssembly 앱을 호스트하는 방법에 대한 자세한 내용은 호스트된 여러 ASP.NET Core Blazor WebAssembly 앱을 참조하세요.

배포

배포 지침은 다음 항목을 참조하세요.