共用方式為


整合 ASP.NET Core Razor 元件與MVC或 Razor Pages

注意

這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。

警告

不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前的版本,請參閱 本文的 .NET 9 版本。

Razor 元件可以整合到 Razor Pages 或 MVC 應用程式中。 轉譯頁面或檢視時,可以同時預先轉譯元件。

重要

不同 ASP.NET Core 版本的架構變更,導致本文提供了不同的指示集。 使用本文的指引之前,請確認本文頂端的檔版本選取器符合您想要用於應用程式的 ASP.NET Core 版本。

預先轉譯可藉由轉譯初始 HTTP 回應的內容來改善搜尋引擎最佳化 (SEO),讓搜尋引擎可使用該回應來計算頁面排名。

設定專案之後,請根據專案的需求使用以下幾節中的指引:

組態

使用下列指引,將元件整合到 Razor 現有 Razor Pages或MVC應用程式的頁面或檢視中。

  1. 將具有下列內容的匯入檔案新增至專案的根資料夾。 將 {APP NAMESPACE} 預留位置變更為專案的命名空間。

    _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 {APP NAMESPACE}
    
  2. 在專案的配置檔案 (在 Razor Pages 應用程式中的 Pages/Shared/_Layout.cshtml 或 MVC 應用程式中的 Views/Shared/_Layout.cshtml) 中:

    • 將下列 <base> 標籤和 HeadOutlet 元件標籤協助程式新增至 <head> 元素:

      <base href="~/" />
      <component type="typeof(Microsoft.AspNetCore.Components.Web.HeadOutlet)" 
          render-mode="ServerPrerendered" />
      

      上述範例中的 href 值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/) 中。 如果應用程式是子應用程式,請遵循裝載及部署 ASP.NET Core Blazor (部分機器翻譯) 文章之應用程式基本路徑一節中的指導。

      HeadOutlet 元件是用來轉譯頁面標題 (PageTitle 元件) 和其他由 Razor 元件所設定之標題元素 (HeadContent 元件) 的標題 (<head>) 內容。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制標題內容 (部分機器翻譯)。

    • Scripts 轉譯區段 (@await RenderSectionAsync(...)) 之前立即新增 blazor.server.js 指令碼的 <script> 標記:

      <script src="_framework/blazor.server.js"></script>
      

      架構會將 blazor.server.js 指令碼新增至應用程式。 無須手動將 blazor.server.js 指令碼檔案新增至應用程式。

    注意

    通常配置會透過 _ViewStart.cshtml 檔案載入。

  3. 在註冊服務的 Program.cs 中註冊 Blazor Server 服務:

    builder.Services.AddServerSideBlazor();
    
  4. 將 Blazor 中樞端點新增至對應路由的 Program.cs 的端點。 在 MapRazorPages (Razor Pages) 或 MapControllerRoute (MVC) 的呼叫後面放置以下這一行:

    app.MapBlazorHub();
    
  5. 將元件整合至任何頁面或檢視中。 例如,將 Counter 元件新增至專案的 Shared 資料夾。

    Pages/Shared/Counter.razor (Razor Pages) 或 Views/Shared/Counter.razor (MVC):

    <h1>Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    

    Razor Pages

    在專案的 Razor Pages 應用程式 Index 頁面中,新增 Counter 元件的命名空間,並將元件內嵌至頁面中。 當 Index 頁面載入時,系統會在頁面中轉譯 Counter 元件。 在下列範例中,將 {APP NAMESPACE} 預留位置以專案的命名空間取代。

    Pages/Index.cshtml

    @page
    @using {APP NAMESPACE}.Pages.Shared
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    

    MVC

    在專案的 MVC 應用程式 Index 檢視中,新增 Counter 元件的命名空間,並將元件內嵌至檢視中。 當 Index 檢視載入時,系統會在頁面中轉譯 Counter 元件。 在下列範例中,將 {APP NAMESPACE} 預留位置以專案的命名空間取代。

    Views/Home/Index.cshtml

    @using {APP NAMESPACE}.Views.Shared
    @{
        ViewData["Title"] = "Home Page";
    }
    
    <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    

如需詳細資訊,請參閱從頁面或檢視轉譯元件一節。

在 Razor Pages 應用程式中使用可路由傳送的元件

本節說明如何新增可直接從使用者要求路由傳送的元件。

若要在 Razor Pages 應用程式中支援可路由傳送的 Razor 元件 :

  1. 請遵循 [設定] 區段中的指引。

  2. 將具有下列內容的 App 元件新增至專案根目錄。

    App.razor

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <p role="alert">Sorry, there's nothing at this address.</p>
        </NotFound>
    </Router>
    
  3. 將具有下列內容的 _Host 頁面新增至專案。 將 {APP NAMESPACE} 預留位置取代為應用程式的命名空間。

    Pages/_Host.cshtml

    @page
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    
    <component type="typeof(App)" render-mode="ServerPrerendered" />
    

    注意

    上述範例假設 HeadOutlet 元件和 Blazor 指令碼 (_framework/blazor.server.js) 是由應用程式的配置所轉譯的。 如需詳細資訊,請參閱設定一節。

    RenderMode 會設定 App 元件是否:

    • 預先轉譯至頁面。
    • 在頁面上轉譯為靜態 HTML,或包含從使用者代理程式啟動 Blazor 應用程式所需的資訊。

    如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式

  4. Program.cs 端點中,將 _Host 頁面的低優先順序路由新增為最後一個端點:

    app.MapFallbackToPage("/_Host");
    
  5. 將可路由傳送的元件新增至專案。 下列範例是以 Blazor 專案範本中 Counter 元件為基礎的 RoutableCounter 元件。

    Pages/RoutableCounter.razor

    @page "/routable-counter"
    
    <PageTitle>Routable Counter</PageTitle>
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  6. 執行專案並瀏覽至位於 /routable-counter 之可路由傳送的 RoutableCounter 元件。

如需命名空間的詳細資訊,請參閱元件命名空間一節。

在 MVC 應用程式中使用可路由傳送的元件

本節說明如何新增可直接從使用者要求路由傳送的元件。

若要在 MVC 應用程式中支援可路由傳送的 Razor 元件:

  1. 請遵循 [設定] 區段中的指引。

  2. 將具有下列內容的 App 元件新增至專案根目錄。

    App.razor

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <p role="alert">Sorry, there's nothing at this address.</p>
        </NotFound>
    </Router>
    
  3. 將具有下列內容的 _Host 檢視新增至專案。 將 {APP NAMESPACE} 預留位置取代為應用程式的命名空間。

    Views/Home/_Host.cshtml

    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    
    <component type="typeof(App)" render-mode="ServerPrerendered" />
    

    注意

    上述範例假設 HeadOutlet 元件和 Blazor 指令碼 (_framework/blazor.server.js) 是由應用程式的配置所轉譯的。 如需詳細資訊,請參閱設定一節。

    RenderMode 會設定 App 元件是否:

    • 預先轉譯至頁面。
    • 在頁面上轉譯為靜態 HTML,或包含從使用者代理程式啟動 Blazor 應用程式所需的資訊。

    如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式

  4. 將動作新增至 Home 控制器。

    Controllers/HomeController.cs

    public IActionResult Blazor()
    {
       return View("_Host");
    }
    
  5. Program.cs 端點中,為傳回 _Host 檢視的控制器動作新增低優先順序路由:

    app.MapFallbackToController("Blazor", "Home");
    
  6. 在 MVC 應用程式中建立 Pages 資料夾,並新增可路由傳送的元件。 下列範例是以 Blazor 專案範本中 Counter 元件為基礎的 RoutableCounter 元件。

    Pages/RoutableCounter.razor

    @page "/routable-counter"
    
    <PageTitle>Routable Counter</PageTitle>
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  7. 執行專案並瀏覽至位於 /routable-counter 之可路由傳送的 RoutableCounter 元件。

如需命名空間的詳細資訊,請參閱元件命名空間一節。

從頁面或檢視轉譯元件

本節說明在無法直接從使用者要求路由傳送元件的情況下,如何將元件新增至頁面或檢視。

若要從頁面或檢視轉譯元件,請使用元件標籤協助程式

轉譯具狀態互動式元件

具狀態互動式元件可以新增至 Razor 頁面或檢視。

當頁面或檢視轉譯時:

  • 元件會與頁面或檢視一起預先轉譯。
  • 用於預先轉譯的初始元件狀態會遺失。
  • 在建立 SignalR 連線時會隨即建立新的元件狀態。

下列 Razor 頁面會轉譯 Counter 元件:

<h1>Razor Page</h1>

<component type="typeof(Counter)" render-mode="ServerPrerendered" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。

轉譯非互動式元件

在下列 Razor 頁面中,Counter 元件會以使用表單指定的初始值,以靜態方式轉譯。 由於元件以靜態方式轉譯,因此元件不具互動性:

<h1>Razor Page</h1>

<form>
    <input type="number" asp-for="InitialValue" />
    <button type="submit">Set initial value</button>
</form>

<component type="typeof(Counter)" render-mode="Static" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。

元件命名空間

在使用自訂資料夾來保存專案的 Razor 元件時,請將代表資料夾的命名空間新增至頁面/檢視或 _ViewImports.cshtml 檔案中。 在以下範例中:

  • 元件會儲存在專案的 Components 資料夾中。
  • {APP NAMESPACE} 預留位置是專案的命名空間。 Components 代表資料夾的名稱。
@using {APP NAMESPACE}.Components

_ViewImports.cshtml 檔案位於 Razor Pages 應用程式的 Pages 資料夾或 MVC 應用程式的 Views 資料夾中。

如需詳細資訊,請參閱 ASP.NET Core Razor 元件

保存預先轉譯的狀態

若未保存預先轉譯的狀態,在預先轉譯期間所使用的狀態會遺失,而且必須在應用程式完全載入時重建。 如果以非同步方式設定了任何狀態,UI 可能會閃動,因為預先轉譯的 UI 會取代為暫時的預留位置,然後再次完整轉譯。

若要保存預先轉譯元件的狀態,請使用保存元件狀態標記協助程式 (參考來源)。 在預先轉譯元件的應用程式中 _Host 頁面的結尾 </body> 標記內,新增標記協助程式的標記 <persist-component-state />

注意

.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

Blazor在Pages/_Host.cshtml應用程式中ServerPrerenderedBlazor Server的應用程式:

<body>
    ...

    <persist-component-state />
</body>

使用 PersistentComponentState 服務決定要保存哪個狀態。 PersistentComponentState.RegisterOnPersisting 會註冊回呼,以在應用程式暫停前保存元件狀態。 應用程式繼續時會擷取此狀態。

在以下範例中:

  • {TYPE} 預留位置代表要保存的資料類型 (例如 WeatherForecast[])。
  • {TOKEN} 預留位置是狀態識別碼字串 (例如 fetchdata)。
@implements IDisposable
@inject PersistentComponentState ApplicationState

...

@code {
    private {TYPE} data;
    private PersistingComponentStateSubscription persistingSubscription;

    protected override async Task OnInitializedAsync()
    {
        persistingSubscription = 
            ApplicationState.RegisterOnPersisting(PersistData);

        if (!ApplicationState.TryTakeFromJson<{TYPE}>(
            "{TOKEN}", out var restored))
        {
            data = await ...;
        }
        else
        {
            data = restored!;
        }
    }

    private Task PersistData()
    {
        ApplicationState.PersistAsJson("{TOKEN}", data);

        return Task.CompletedTask;
    }

    void IDisposable.Dispose()
    {
        persistingSubscription.Dispose();
    }
}

下列範例是以專案範本為基礎的Blazor元件更新版本FetchDataWeatherForecastPreserveState 元件會在預先轉譯期間保存氣象預報狀態,然後擷取該狀態以初始化元件。 保存元件狀態標籤協助程式會在所有元件叫用之後保存元件狀態。

Pages/WeatherForecastPreserveState.razor

@page "/weather-forecast-preserve-state"
@using BlazorSample.Shared
@implements IDisposable
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState

<PageTitle>Weather Forecast</PageTitle>

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
    private PersistingComponentStateSubscription persistingSubscription;

    protected override async Task OnInitializedAsync()
    {
        persistingSubscription = 
            ApplicationState.RegisterOnPersisting(PersistForecasts);

        if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
            "fetchdata", out var restored))
        {
            forecasts = 
                await WeatherForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
        }
        else
        {
            forecasts = restored!;
        }
    }

    private Task PersistForecasts()
    {
        ApplicationState.PersistAsJson("fetchdata", forecasts);

        return Task.CompletedTask;
    }

    void IDisposable.Dispose()
    {
        persistingSubscription.Dispose();
    }
}

在預先轉譯期間使用相同的狀態初始化元件,任何昂貴的初始化步驟只會執行一次。 轉譯的 UI 也會符合預先轉譯的 UI,因此瀏覽器中不會發生閃爍。

保存的預先呈現狀態會傳送至用戶端,用來還原元件狀態。 ASP.NET Core Data Protection 可確保在應用程式中安全地 Blazor Server 傳輸數據。

預先轉譯狀態大小和 SignalR 訊息大小限制

大型預先呈現的狀態大小可能超過 Blazor線路 SignalR 訊息大小限制,這會導致下列結果:

  • SignalR 線路無法初始化,且用戶端發生錯誤:Circuit host not initialized.
  • 當線路發生中斷時,用戶端會出現重新連線的 UI。 不可能復原。

若要解決該問題,請使用下列任一種方法:

  • 減少放入預先轉譯狀態的資料量。
  • 新增 SignalR 訊息大小限制警告:增加限制可能會增加拒絕服務 (DoS) 攻擊的風險。

其他 Blazor Server 資源

預先轉譯可藉由轉譯初始 HTTP 回應的內容來改善搜尋引擎最佳化 (SEO),讓搜尋引擎可使用該回應來計算頁面排名。

設定專案之後,請根據專案的需求使用以下幾節中的指引:

組態

使用下列指引,將元件整合到 Razor 現有 Razor Pages或MVC應用程式的頁面或檢視中。

重要

必須使用配置頁面 (_Layout.cshtml) 搭配 HeadOutlet 元件的元件標籤協助程式,以控制 <head> 內容,例如頁面的標題 (PageTitle 元件) 和其他標頭元素 (HeadContent 元件)。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制標題內容 (部分機器翻譯)。

  1. 在專案的配置檔案中:

    • 將下列 <base> 標籤和 HeadOutlet 元件標籤協助程式新增至 Pages/Shared/_Layout.cshtml (Razor Pages) 或 Views/Shared/_Layout.cshtml (MVC) 中的 <head> 元素:

      <base href="~/" />
      <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
      

      上述範例中的 href 值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/) 中。 如果應用程式是子應用程式,請遵循裝載及部署 ASP.NET Core Blazor (部分機器翻譯) 文章之應用程式基本路徑一節中的指導。

      HeadOutlet 元件是用來轉譯頁面標題 (PageTitle 元件) 和其他由 Razor 元件所設定之標題元素 (HeadContent 元件) 的標題 (<head>) 內容。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制標題內容 (部分機器翻譯)。

    • 在應用程式的配置中,在 Scripts 轉譯區段 (@await RenderSectionAsync(...)) 前面新增 blazor.server.js 指令碼的 <script> 標籤。

      Pages/Shared/_Layout.cshtml (Razor Pages) 或 Views/Shared/_Layout.cshtml (MVC):

      <script src="_framework/blazor.server.js"></script>
      

      架構會將 blazor.server.js 指令碼新增至應用程式。 無須手動將 blazor.server.js 指令碼檔案新增至應用程式。

  2. 將具有下列內容的匯入檔案新增至專案的根資料夾。 將 {APP NAMESPACE} 預留位置變更為專案的命名空間。

    _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 {APP NAMESPACE}
    
  3. 在註冊服務的 Program.cs 中註冊 Blazor Server 服務:

    builder.Services.AddServerSideBlazor();
    
  4. 將 Blazor 中樞端點新增至對應路由的 Program.cs 的端點。

    MapRazorPages (Razor Pages) 或 MapControllerRoute (MVC) 的呼叫後面放置以下這一行:

    app.MapBlazorHub();
    
  5. 將元件整合至任何頁面或檢視中。 例如,將 Counter 元件新增至專案的 Shared 資料夾。

    Pages/Shared/Counter.razor (Razor Pages) 或 Views/Shared/Counter.razor (MVC):

    <h1>Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    

    Razor Pages

    在專案的 Razor Pages 應用程式 Index 頁面中,新增 Counter 元件的命名空間,並將元件內嵌至頁面中。 當 Index 頁面載入時,系統會在頁面中轉譯 Counter 元件。 在下列範例中,將 {APP NAMESPACE} 預留位置以專案的命名空間取代。

    Pages/Index.cshtml

    @page
    @using {APP NAMESPACE}.Pages.Shared
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    

    MVC

    在專案的 MVC 應用程式 Index 檢視中,新增 Counter 元件的命名空間,並將元件內嵌至檢視中。 當 Index 檢視載入時,系統會在頁面中轉譯 Counter 元件。 在下列範例中,將 {APP NAMESPACE} 預留位置以專案的命名空間取代。

    Views/Home/Index.cshtml

    @using {APP NAMESPACE}.Views.Shared
    @{
        ViewData["Title"] = "Home Page";
    }
    
    <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    

如需詳細資訊,請參閱從頁面或檢視轉譯元件一節。

在 Razor Pages 應用程式中使用可路由傳送的元件

本節說明如何新增可直接從使用者要求路由傳送的元件。

若要在 Razor Pages 應用程式中支援可路由傳送的 Razor 元件 :

  1. 請遵循 [設定] 區段中的指引。

  2. 將具有下列內容的 App 元件新增至專案根目錄。

    App.razor

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <p role="alert">Sorry, there's nothing at this address.</p>
        </NotFound>
    </Router>
    
  3. 將具有下列內容的 _Host 頁面新增至專案。

    Pages/_Host.cshtml

    @page "/blazor"
    @namespace {APP NAMESPACE}.Pages.Shared
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    @{
        Layout = "_Layout";
    }
    
    <component type="typeof(App)" render-mode="ServerPrerendered" />
    

    在此案例中,元件會使用共用的 _Layout.cshtml 檔案進行其配置。

    重要

    必須使用配置頁面 (_Layout.cshtml) 搭配 HeadOutlet 元件的元件標籤協助程式,以控制 <head> 內容,例如頁面的標題 (PageTitle 元件) 和其他標頭元素 (HeadContent 元件)。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制標題內容 (部分機器翻譯)。

    RenderMode 會設定 App 元件是否:

    • 預先轉譯至頁面。
    • 在頁面上轉譯為靜態 HTML,或包含從使用者代理程式啟動 Blazor 應用程式所需的資訊。

    如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式

  4. Program.cs 端點中,將 _Host 頁面的低優先順序路由新增為最後一個端點:

    app.MapFallbackToPage("/_Host");
    
  5. 將可路由傳送的元件新增至專案。 下列範例是以 Blazor 專案範本中 Counter 元件為基礎的 RoutableCounter 元件。

    Pages/RoutableCounter.razor

    @page "/routable-counter"
    
    <PageTitle>Routable Counter</PageTitle>
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  6. 執行專案並瀏覽至位於 /routable-counter 之可路由傳送的 RoutableCounter 元件。

如需命名空間的詳細資訊,請參閱元件命名空間一節。

在 MVC 應用程式中使用可路由傳送的元件

本節說明如何新增可直接從使用者要求路由傳送的元件。

若要在 MVC 應用程式中支援可路由傳送的 Razor 元件:

  1. 請遵循 [設定] 區段中的指引。

  2. 將具有下列內容的 App 元件新增至專案根目錄。

    App.razor

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <p role="alert">Sorry, there's nothing at this address.</p>
        </NotFound>
    </Router>
    
  3. 將具有下列內容的 _Host 檢視新增至專案。

    Views/Home/_Host.cshtml

    @namespace {APP NAMESPACE}.Views.Shared
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    @{
        Layout = "_Layout";
    }
    
    <component type="typeof(App)" render-mode="ServerPrerendered" />
    

    元件會使用共用的 _Layout.cshtml 檔案進行其配置。

    重要

    必須使用配置頁面 (_Layout.cshtml) 搭配 HeadOutlet 元件的元件標籤協助程式,以控制 <head> 內容,例如頁面的標題 (PageTitle 元件) 和其他標頭元素 (HeadContent 元件)。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制標題內容 (部分機器翻譯)。

    RenderMode 會設定 App 元件是否:

    • 預先轉譯至頁面。
    • 在頁面上轉譯為靜態 HTML,或包含從使用者代理程式啟動 Blazor 應用程式所需的資訊。

    如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式

  4. 將動作新增至 Home 控制器。

    Controllers/HomeController.cs

    public IActionResult Blazor()
    {
       return View("_Host");
    }
    
  5. Program.cs 端點中,為傳回 _Host 檢視的控制器動作新增低優先順序路由:

    app.MapFallbackToController("Blazor", "Home");
    
  6. 在 MVC 應用程式中建立 Pages 資料夾,並新增可路由傳送的元件。 下列範例是以 Blazor 專案範本中 Counter 元件為基礎的 RoutableCounter 元件。

    Pages/RoutableCounter.razor

    @page "/routable-counter"
    
    <PageTitle>Routable Counter</PageTitle>
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  7. 執行專案並瀏覽至位於 /routable-counter 之可路由傳送的 RoutableCounter 元件。

如需命名空間的詳細資訊,請參閱元件命名空間一節。

從頁面或檢視轉譯元件

本節說明在無法直接從使用者要求路由傳送元件的情況下,如何將元件新增至頁面或檢視。

若要從頁面或檢視轉譯元件,請使用元件標籤協助程式

轉譯具狀態互動式元件

具狀態互動式元件可以新增至 Razor 頁面或檢視。

當頁面或檢視轉譯時:

  • 元件會與頁面或檢視一起預先轉譯。
  • 用於預先轉譯的初始元件狀態會遺失。
  • 在建立 SignalR 連線時會隨即建立新的元件狀態。

下列 Razor 頁面會轉譯 Counter 元件:

<h1>Razor Page</h1>

<component type="typeof(Counter)" render-mode="ServerPrerendered" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。

重要

必須使用配置頁面 (_Layout.cshtml) 搭配 HeadOutlet 元件的元件標籤協助程式,以控制 <head> 內容,例如頁面的標題 (PageTitle 元件) 和其他標頭元素 (HeadContent 元件)。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制標題內容 (部分機器翻譯)。

轉譯非互動式元件

在下列 Razor 頁面中,Counter 元件會以使用表單指定的初始值,以靜態方式轉譯。 由於元件以靜態方式轉譯,因此元件不具互動性:

<h1>Razor Page</h1>

<form>
    <input type="number" asp-for="InitialValue" />
    <button type="submit">Set initial value</button>
</form>

<component type="typeof(Counter)" render-mode="Static" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。

重要

必須使用配置頁面 (_Layout.cshtml) 搭配 HeadOutlet 元件的元件標籤協助程式,以控制 <head> 內容,例如頁面的標題 (PageTitle 元件) 和其他標頭元素 (HeadContent 元件)。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制標題內容 (部分機器翻譯)。

元件命名空間

在使用自訂資料夾來保存專案的 Razor 元件時,請將代表資料夾的命名空間新增至頁面/檢視或 _ViewImports.cshtml 檔案中。 在以下範例中:

  • 元件會儲存在專案的 Components 資料夾中。
  • {APP NAMESPACE} 預留位置是專案的命名空間。 Components 代表資料夾的名稱。
@using {APP NAMESPACE}.Components

_ViewImports.cshtml 檔案位於 Razor Pages 應用程式的 Pages 資料夾或 MVC 應用程式的 Views 資料夾中。

如需詳細資訊,請參閱 ASP.NET Core Razor 元件

保存預先轉譯的狀態

若未保存預先轉譯的狀態,在預先轉譯期間所使用的狀態會遺失,而且必須在應用程式完全載入時重建。 如果以非同步方式設定了任何狀態,UI 可能會閃動,因為預先轉譯的 UI 會取代為暫時的預留位置,然後再次完整轉譯。

為了解決這些問題,Blazor 支援使用保存元件狀態標籤協助程式在預先轉譯的頁面中保存狀態。 在結尾 </body> 標籤內新增標籤協助程式的標籤 <persist-component-state />

Pages/_Layout.cshtml

<body>
    ...

    <persist-component-state />
</body>

使用 PersistentComponentState 服務決定要保存哪個狀態。 PersistentComponentState.RegisterOnPersisting 會註冊回呼,以在應用程式暫停前保存元件狀態。 應用程式繼續時會擷取此狀態。

下列範例是以專案範本為基礎的Blazor元件更新版本FetchDataWeatherForecastPreserveState 元件會在預先轉譯期間保存氣象預報狀態,然後擷取該狀態以初始化元件。 保存元件狀態標籤協助程式會在所有元件叫用之後保存元件狀態。

Pages/WeatherForecastPreserveState.razor

@page "/weather-forecast-preserve-state"
@implements IDisposable
@using BlazorSample.Shared
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState

<PageTitle>Weather Forecast</PageTitle>

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
    private PersistingComponentStateSubscription persistingSubscription;

    protected override async Task OnInitializedAsync()
    {
        persistingSubscription = 
            ApplicationState.RegisterOnPersisting(PersistForecasts);

        if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
            "fetchdata", out var restored))
        {
            forecasts = 
                await WeatherForecastService.GetForecastAsync(DateTime.Now);
        }
        else
        {
            forecasts = restored!;
        }
    }

    private Task PersistForecasts()
    {
        ApplicationState.PersistAsJson("fetchdata", forecasts);

        return Task.CompletedTask;
    }

    void IDisposable.Dispose()
    {
        persistingSubscription.Dispose();
    }
}

在預先轉譯期間使用相同的狀態初始化元件,任何昂貴的初始化步驟只會執行一次。 轉譯的 UI 也會符合預先轉譯的 UI,因此瀏覽器中不會發生閃爍。

保存的預先呈現狀態會傳送至用戶端,用來還原元件狀態。 ASP.NET Core Data Protection 可確保在應用程式中安全地 Blazor Server 傳輸數據。

預先轉譯狀態大小和 SignalR 訊息大小限制

大型預先呈現的狀態大小可能超過 Blazor線路 SignalR 訊息大小限制,這會導致下列結果:

  • SignalR 線路無法初始化,且用戶端發生錯誤:Circuit host not initialized.
  • 當線路發生中斷時,用戶端會出現重新連線的 UI。 不可能復原。

若要解決該問題,請使用下列任一種方法:

  • 減少放入預先轉譯狀態的資料量。
  • 新增 SignalR 訊息大小限制警告:增加限制可能會增加拒絕服務 (DoS) 攻擊的風險。

其他 Blazor Server 資源

預先轉譯可藉由轉譯初始 HTTP 回應的內容來改善搜尋引擎最佳化 (SEO),讓搜尋引擎可使用該回應來計算頁面排名。

設定專案之後,請根據專案的需求使用以下幾節中的指引:

組態

現有的 Razor Pages 或 MVC 應用程式可以將元件整合到 Razor 頁面或檢視中:

  1. 在專案的配置檔案中:

    • 將下列 <base> 標籤新增至 Pages/Shared/_Layout.cshtml (Razor Pages) 或 Views/Shared/_Layout.cshtml (MVC) 中的 <head> 元素:

      <base href="~/" />
      

      上述範例中的 href 值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/) 中。 如果應用程式是子應用程式,請遵循裝載及部署 ASP.NET Core Blazor (部分機器翻譯) 文章之應用程式基本路徑一節中的指導。

    • Scripts 轉譯區段前面新增 blazor.server.js 指令碼的 <script> 標籤。

      Pages/Shared/_Layout.cshtml (Razor Pages) 或 Views/Shared/_Layout.cshtml (MVC):

          ...
          <script src="_framework/blazor.server.js"></script>
      
          @await RenderSectionAsync("Scripts", required: false)
      </body>
      

      架構會將 blazor.server.js 指令碼新增至應用程式。 無須手動將 blazor.server.js 指令碼檔案新增至應用程式。

  2. 將具有下列內容的匯入檔案新增至專案的根資料夾。 將 {APP NAMESPACE} 預留位置變更為專案的命名空間。

    _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.JSInterop
    @using {APP NAMESPACE}
    
  3. Startup.ConfigureServices 中註冊 Blazor Server 服務。

    Startup.cs 中:

    services.AddServerSideBlazor();
    
  4. 將 Blazor 中樞端點新增至 Startup.Configure 的端點 (app.UseEndpoints)。

    Startup.cs

    endpoints.MapBlazorHub();
    
  5. 將元件整合至任何頁面或檢視中。 例如,將 Counter 元件新增至專案的 Shared 資料夾。

    Pages/Shared/Counter.razor (Razor Pages) 或 Views/Shared/Counter.razor (MVC):

    <h1>Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    

    Razor Pages

    在專案的 Razor Pages 應用程式 Index 頁面中,新增 Counter 元件的命名空間,並將元件內嵌至頁面中。 當 Index 頁面載入時,系統會在頁面中轉譯 Counter 元件。 在下列範例中,將 {APP NAMESPACE} 預留位置以專案的命名空間取代。

    Pages/Index.cshtml

    @page
    @using {APP NAMESPACE}.Pages.Shared
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div>
        <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    </div>
    

    在上述範例中,將 {APP NAMESPACE} 預留位置取代為應用程式的命名空間。

    MVC

    在專案的 MVC 應用程式 Index 檢視中,新增 Counter 元件的命名空間,並將元件內嵌至檢視中。 當 Index 檢視載入時,系統會在頁面中轉譯 Counter 元件。 在下列範例中,將 {APP NAMESPACE} 預留位置以專案的命名空間取代。

    Views/Home/Index.cshtml

    @using {APP NAMESPACE}.Views.Shared
    @{
        ViewData["Title"] = "Home Page";
    }
    
    <div>
        <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    </div>
    

如需詳細資訊,請參閱從頁面或檢視轉譯元件一節。

在 Razor Pages 應用程式中使用可路由傳送的元件

本節說明如何新增可直接從使用者要求路由傳送的元件。

若要在 Razor Pages 應用程式中支援可路由傳送的 Razor 元件 :

  1. 請遵循 [設定] 區段中的指引。

  2. 將具有下列內容的 App 元件新增至專案根目錄。

    App.razor

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="typeof(Program).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <h1>Page not found</h1>
            <p>Sorry, but there's nothing here!</p>
        </NotFound>
    </Router>
    

    注意

    隨著 ASP.NET Core 5.0.1 的發行以及在任何其他 5.x 版中,Router 元件會包含設定為 @truePreferExactMatches 參數。 如需詳細資訊,請參閱從 ASP.NET Core 3.1 移轉至 5.0

  3. 將具有下列內容的 _Host 頁面新增至專案。

    Pages/_Host.cshtml

    @page "/blazor"
    @{
        Layout = "_Layout";
    }
    
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
    

    元件會使用共用的 _Layout.cshtml 檔案進行其配置。

    RenderMode 會設定 App 元件是否:

    • 預先轉譯至頁面。
    • 在頁面上轉譯為靜態 HTML,或包含從使用者代理程式啟動 Blazor 應用程式所需的資訊。

    如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式

  4. Startup.csStartup.Configure 端點中,將 _Host 頁面的低優先順序路由新增為最後一個端點:

    endpoints.MapFallbackToPage("/_Host");
    

    下列範例顯示一般應用程式端點設定中新增的行:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
    
  5. 將可路由傳送的元件新增至專案。

    Pages/RoutableCounter.razor

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  6. 執行專案並瀏覽至位於 /routable-counter 之可路由傳送的 RoutableCounter 元件。

如需命名空間的詳細資訊,請參閱元件命名空間一節。

在 MVC 應用程式中使用可路由傳送的元件

本節說明如何新增可直接從使用者要求路由傳送的元件。

若要在 MVC 應用程式中支援可路由傳送的 Razor 元件:

  1. 請遵循 [設定] 區段中的指引。

  2. 將具有下列內容的 App 元件新增至專案根目錄。

    App.razor

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="typeof(Program).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <h1>Page not found</h1>
            <p>Sorry, but there's nothing here!</p>
        </NotFound>
    </Router>
    

    注意

    隨著 ASP.NET Core 5.0.1 的發行以及在任何其他 5.x 版中,Router 元件會包含設定為 @truePreferExactMatches 參數。 如需詳細資訊,請參閱從 ASP.NET Core 3.1 移轉至 5.0

  3. 將具有下列內容的 _Host 檢視新增至專案。

    Views/Home/_Host.cshtml

    @{
        Layout = "_Layout";
    }
    
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
    

    元件會使用共用的 _Layout.cshtml 檔案進行其配置。

    RenderMode 會設定 App 元件是否:

    • 預先轉譯至頁面。
    • 在頁面上轉譯為靜態 HTML,或包含從使用者代理程式啟動 Blazor 應用程式所需的資訊。

    如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式

  4. 將動作新增至 Home 控制器。

    Controllers/HomeController.cs

    public IActionResult Blazor()
    {
       return View("_Host");
    }
    
  5. Startup.csStartup.Configure 端點中,為傳回 _Host 檢視的控制器動作新增低優先順序路由:

    endpoints.MapFallbackToController("Blazor", "Home");
    

    下列範例顯示一般應用程式端點設定中新增的行:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToController("Blazor", "Home");
    });
    
  6. 將可路由傳送的元件新增至專案。

    Pages/RoutableCounter.razor

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  7. 執行專案並瀏覽至位於 /routable-counter 之可路由傳送的 RoutableCounter 元件。

如需命名空間的詳細資訊,請參閱元件命名空間一節。

從頁面或檢視轉譯元件

本節說明在無法直接從使用者要求路由傳送元件的情況下,如何將元件新增至頁面或檢視。

若要從頁面或檢視轉譯元件,請使用元件標籤協助程式

轉譯具狀態互動式元件

具狀態互動式元件可以新增至 Razor 頁面或檢視。

當頁面或檢視轉譯時:

  • 元件會與頁面或檢視一起預先轉譯。
  • 用於預先轉譯的初始元件狀態會遺失。
  • 在建立 SignalR 連線時會隨即建立新的元件狀態。

下列 Razor 頁面會轉譯 Counter 元件:

<h1>My Razor Page</h1>

<component type="typeof(Counter)" render-mode="ServerPrerendered" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。

轉譯非互動式元件

在下列 Razor 頁面中,Counter 元件會以使用表單指定的初始值,以靜態方式轉譯。 由於元件以靜態方式轉譯,因此元件不具互動性:

<h1>My Razor Page</h1>

<form>
    <input type="number" asp-for="InitialValue" />
    <button type="submit">Set initial value</button>
</form>

<component type="typeof(Counter)" render-mode="Static" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。

元件命名空間

在使用自訂資料夾來保存專案的 Razor 元件時,請將代表資料夾的命名空間新增至頁面/檢視或 _ViewImports.cshtml 檔案中。 在以下範例中:

  • 元件會儲存在專案的 Components 資料夾中。
  • {APP NAMESPACE} 預留位置是專案的命名空間。 Components 代表資料夾的名稱。
@using {APP NAMESPACE}.Components

_ViewImports.cshtml 檔案位於 Razor Pages 應用程式的 Pages 資料夾或 MVC 應用程式的 Views 資料夾中。

如需詳細資訊,請參閱 ASP.NET Core Razor 元件

預先轉譯狀態大小和 SignalR 訊息大小限制

大型預先呈現的狀態大小可能超過 Blazor線路 SignalR 訊息大小限制,這會導致下列結果:

  • SignalR 線路無法初始化,且用戶端發生錯誤:Circuit host not initialized.
  • 當線路發生中斷時,用戶端會出現重新連線的 UI。 不可能復原。

若要解決該問題,請使用下列任一種方法:

  • 減少放入預先轉譯狀態的資料量。
  • 新增 SignalR 訊息大小限制警告:增加限制可能會增加拒絕服務 (DoS) 攻擊的風險。

其他 Blazor Server 資源

Razor 元件可以整合到 Razor Pages 或 MVC 應用程式中。 轉譯頁面或檢視時,可以同時預先轉譯元件。

預先轉譯可藉由轉譯初始 HTTP 回應的內容來改善搜尋引擎最佳化 (SEO),讓搜尋引擎可使用該回應來計算頁面排名。

設定專案之後,請根據專案的需求使用以下幾節中的指引:

組態

現有的 Razor Pages 或 MVC 應用程式可以將元件整合到 Razor 頁面或檢視中:

  1. 在專案的配置檔案中:

    • 將下列 <base> 標籤新增至 Pages/Shared/_Layout.cshtml (Razor Pages) 或 Views/Shared/_Layout.cshtml (MVC) 中的 <head> 元素:

      + <base href="~/" />
      

      上述範例中的 href 值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/) 中。 如果應用程式是子應用程式,請遵循裝載及部署 ASP.NET Core Blazor (部分機器翻譯) 文章之應用程式基本路徑一節中的指導。

    • Scripts 轉譯區段前面新增 blazor.server.js 指令碼的 <script> 標籤。

      Pages/Shared/_Layout.cshtml (Razor Pages) 或 Views/Shared/_Layout.cshtml (MVC):

          ...
          <script src="_framework/blazor.server.js"></script>
      
          @await RenderSectionAsync("Scripts", required: false)
      </body>
      

      架構會將 blazor.server.js 指令碼新增至應用程式。 無須手動將 blazor.server.js 指令碼檔案新增至應用程式。

  2. 將具有下列內容的匯入檔案新增至專案的根資料夾。 將 {APP NAMESPACE} 預留位置變更為專案的命名空間。

    _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.JSInterop
    @using {APP NAMESPACE}
    
  3. Startup.ConfigureServices 中註冊 Blazor Server 服務。

    Startup.cs

    services.AddServerSideBlazor();
    
  4. 將 Blazor 中樞端點新增至 Startup.Configure 的端點 (app.UseEndpoints)。

    Startup.cs

    endpoints.MapBlazorHub();
    
  5. 將元件整合至任何頁面或檢視中。 例如,將 Counter 元件新增至專案的 Shared 資料夾。

    Pages/Shared/Counter.razor (Razor Pages) 或 Views/Shared/Counter.razor (MVC):

    <h1>Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    

    Razor Pages

    在專案的 Razor Pages 應用程式 Index 頁面中,新增 Counter 元件的命名空間,並將元件內嵌至頁面中。 當 Index 頁面載入時,系統會在頁面中轉譯 Counter 元件。 在下列範例中,將 {APP NAMESPACE} 預留位置以專案的命名空間取代。

    Pages/Index.cshtml

    @page
    @using {APP NAMESPACE}.Pages.Shared
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div>
        <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    </div>
    

    在上述範例中,將 {APP NAMESPACE} 預留位置取代為應用程式的命名空間。

    MVC

    在專案的 MVC 應用程式 Index 檢視中,新增 Counter 元件的命名空間,並將元件內嵌至檢視中。 當 Index 檢視載入時,系統會在頁面中轉譯 Counter 元件。 在下列範例中,將 {APP NAMESPACE} 預留位置以專案的命名空間取代。

    Views/Home/Index.cshtml

    @using {APP NAMESPACE}.Views.Shared
    @{
        ViewData["Title"] = "Home Page";
    }
    
    <div>
        <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    </div>
    

如需詳細資訊,請參閱從頁面或檢視轉譯元件一節。

在 Razor Pages 應用程式中使用可路由傳送的元件

本節說明如何新增可直接從使用者要求路由傳送的元件。

若要在 Razor Pages 應用程式中支援可路由傳送的 Razor 元件 :

  1. 請遵循 [設定] 區段中的指引。

  2. 將具有下列內容的 App 元件新增至專案根目錄。

    App.razor

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="typeof(Program).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <h1>Page not found</h1>
            <p>Sorry, but there's nothing here!</p>
        </NotFound>
    </Router>
    
  3. 將具有下列內容的 _Host 頁面新增至專案。

    Pages/_Host.cshtml

    @page "/blazor"
    @{
        Layout = "_Layout";
    }
    
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
    

    元件會使用共用的 _Layout.cshtml 檔案進行其配置。

    RenderMode 會設定 App 元件是否:

    • 預先轉譯至頁面。
    • 在頁面上轉譯為靜態 HTML,或包含從使用者代理程式啟動 Blazor 應用程式所需的資訊。

    如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式

  4. Startup.csStartup.Configure 端點中,將 _Host 頁面的低優先順序路由新增為最後一個端點:

    endpoints.MapFallbackToPage("/_Host");
    

    下列範例顯示一般應用程式端點設定中新增的行:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
    
  5. 將可路由傳送的元件新增至專案。

    Pages/RoutableCounter.razor

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  6. 執行專案並瀏覽至位於 /routable-counter 之可路由傳送的 RoutableCounter 元件。

如需命名空間的詳細資訊,請參閱元件命名空間一節。

在 MVC 應用程式中使用可路由傳送的元件

本節說明如何新增可直接從使用者要求路由傳送的元件。

若要在 MVC 應用程式中支援可路由傳送的 Razor 元件:

  1. 請遵循 [設定] 區段中的指引。

  2. 將具有下列內容的 App 元件新增至專案根目錄。

    App.razor

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="typeof(Program).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <h1>Page not found</h1>
            <p>Sorry, but there's nothing here!</p>
        </NotFound>
    </Router>
    
  3. 將具有下列內容的 _Host 檢視新增至專案。

    Views/Home/_Host.cshtml

    @{
        Layout = "_Layout";
    }
    
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
    

    元件會使用共用的 _Layout.cshtml 檔案進行其配置。

    RenderMode 會設定 App 元件是否:

    • 預先轉譯至頁面。
    • 在頁面上轉譯為靜態 HTML,或包含從使用者代理程式啟動 Blazor 應用程式所需的資訊。

    如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式

  4. 將動作新增至 Home 控制器。

    Controllers/HomeController.cs

    public IActionResult Blazor()
    {
       return View("_Host");
    }
    
  5. Startup.csStartup.Configure 端點中,為傳回 _Host 檢視的控制器動作新增低優先順序路由:

    endpoints.MapFallbackToController("Blazor", "Home");
    

    下列範例顯示一般應用程式端點設定中新增的行:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToController("Blazor", "Home");
    });
    
  6. 將可路由傳送的元件新增至專案。

    Pages/RoutableCounter.razor

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  7. 執行專案並瀏覽至位於 /routable-counter 之可路由傳送的 RoutableCounter 元件。

如需命名空間的詳細資訊,請參閱元件命名空間一節。

從頁面或檢視轉譯元件

本節說明在無法直接從使用者要求路由傳送元件的情況下,如何將元件新增至頁面或檢視。

若要從頁面或檢視轉譯元件,請使用元件標籤協助程式

轉譯具狀態互動式元件

具狀態互動式元件可以新增至 Razor 頁面或檢視。

當頁面或檢視轉譯時:

  • 元件會與頁面或檢視一起預先轉譯。
  • 用於預先轉譯的初始元件狀態會遺失。
  • 在建立 SignalR 連線時會隨即建立新的元件狀態。

下列 Razor 頁面會轉譯 Counter 元件:

<h1>My Razor Page</h1>

<component type="typeof(Counter)" render-mode="ServerPrerendered" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。

轉譯非互動式元件

在下列 Razor 頁面中,Counter 元件會以使用表單指定的初始值,以靜態方式轉譯。 由於元件以靜態方式轉譯,因此元件不具互動性:

<h1>My Razor Page</h1>

<form>
    <input type="number" asp-for="InitialValue" />
    <button type="submit">Set initial value</button>
</form>

<component type="typeof(Counter)" render-mode="Static" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。

元件命名空間

在使用自訂資料夾來保存專案的 Razor 元件時,請將代表資料夾的命名空間新增至頁面/檢視或 _ViewImports.cshtml 檔案中。 在以下範例中:

  • 元件會儲存在專案的 Components 資料夾中。
  • {APP NAMESPACE} 預留位置是專案的命名空間。 Components 代表資料夾的名稱。
@using {APP NAMESPACE}.Components

_ViewImports.cshtml 檔案位於 Razor Pages 應用程式的 Pages 資料夾或 MVC 應用程式的 Views 資料夾中。

如需詳細資訊,請參閱 ASP.NET Core Razor 元件

預先轉譯狀態大小和 SignalR 訊息大小限制

大型預先呈現的狀態大小可能超過 Blazor線路 SignalR 訊息大小限制,這會導致下列結果:

  • SignalR 線路無法初始化,且用戶端發生錯誤:Circuit host not initialized.
  • 當線路發生中斷時,用戶端會出現重新連線的 UI。 不可能復原。

若要解決該問題,請使用下列任一種方法:

  • 減少放入預先轉譯狀態的資料量。
  • 新增 SignalR 訊息大小限制警告:增加限制可能會增加拒絕服務 (DoS) 攻擊的風險。

其他 Blazor Server 資源