從 .NET 7 中的 ASP.NET Core 移轉至 .NET 8
此文章說明如何將現有的 ASP.NET Core 7.0 專案更新為 ASP.NET Core 8.0。
必要條件
Visual Studio 2022 和 ASP.NET 與 Web 開發工作負載。
更新 global.json
中的 .NET SDK 版本
如果您依賴 global.json
檔案來以特定 .NET Core SDK 版本為目標,請將 version
屬性更新為已安裝的 .NET 8.0 SDK 版本。 例如:
{
"sdk": {
- "version": "7.0.100"
+ "version": "8.0.100"
}
}
更新目標 Framework
將專案檔的目標 Framework Moniker (TFM) 更新為 net8.0
:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
- <TargetFramework>net7.0</TargetFramework>
+ <TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
</Project>
更新套件參考
在專案檔中,將每個 Microsoft.AspNetCore.*
、Microsoft.EntityFrameworkCore.*
、Microsoft.Extensions.*
和 System.Net.Http.Json
套件參考的 Version
屬性更新為 8.0.0 或更新版本。 例如:
<ItemGroup>
- <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="7.0.12" />
- <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.12" />
- <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
- <PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
+ <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="8.0.0" />
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0" />
+ <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
+ <PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
</ItemGroup>
Blazor
涵蓋支援下列移轉案例:
- 更新 Blazor Server 應用程式
- 採用所有 Blazor Web 應用程式慣例
- 將 Blazor Server 應用程式轉換成 Blazor Web 應用程式
- 更新 Blazor WebAssembly 應用程式
- 將裝載的 Blazor WebAssembly 應用程式轉換成 Blazor Web 應用程式
- 更新服務和端點選項群組態
- 使用 Yarp 路由因應措施卸除Blazor Server
- 在配置元件中移轉
CascadingValue
元件 - 移轉
BlazorEnableCompression
MSBuild 屬性 - 將
<CascadingAuthenticationState>
元件移轉至階層式驗證狀態服務 - 新文章:移轉期間的 HTTP 快取問題
- 新文章:關於使用靜態伺服器端轉譯 (靜態 SSR) 的類別庫的新文章
- 探索其他組件中的元件
- 當參數從查詢字串中提供時卸除
[Parameter]
屬性 - Blazor Server 指令碼後援原則授權
如需將 Blazor 支援新增至 ASP.NET Core 應用程式的指導,請參閱 將 ASP.NET CoreRazor 元件整合至 ASP.NET Core 應用程式。
更新 Blazor Server 應用程式
我們建議在 .NET 8 中使用 Blazor Web 應用程式,但 Blazor Server 受到支援。 若要繼續使用 Blazor Server .NET 8,請遵循本文前三節中的指導:
- 更新
global.json
中的 .NET SDK 版本 - 更新目標 Framework
- 更新套件參考
針對 Blazor Web 應用程式引進的新 Blazor 功能不適用於更新為在 .NET 8 下執行的 Blazor Server 應用程式。 如果您想要採用新的 .NET 8 Blazor 功能,請遵循下列任一節中的指導:
採用所有 Blazor Web 應用程式慣例
若要選擇性地採用所有新的 Blazor Web 應用程式慣例,我們建議以下流程:
- 從 Blazor Web 應用程式專案範本建立新的應用程式。 如需詳細資訊,請參閱 ASP.NET Core Blazor 工具。
- 將應用程式的元件和程式碼移至新的 Blazor Web 應用程式,以進行修改以採用新功能。
- 更新 Blazor Web 應用程式的版面配置和樣式。
ASP.NET Core 8.0 的新功能 涵蓋新的 .NET 8 功能。 從 .NET 6 或更早版本更新應用程式時,請參閱移轉和版本資訊 (新功能 文章) 以介入版本。
將 Blazor Server 應用程式轉換成 Blazor Web 應用程式
.NET 8 中支援 Blazor Server 應用程式,而不需要變更任何程式碼。 使用下列指導將 Blazor Server 應用程式轉換成對等的 .NET 8 Blazor Web 應用程式,讓所有 新的 .NET 8 功能 都可供使用。
重要
本章節會著重在將 .NET 7 Blazor Server 應用程式轉換成 .NET 8 Blazor Web 應用程式所需的最小變更。 若要採用所有新的 Blazor Web 應用程式慣例,請遵循採用所有 Blazor Web 應用程式慣例一節中的指導。
請遵循本文前三個章節的指導:
- 更新
global.json
中的 .NET SDK 版本 - 更新目標 Framework
- 更新套件參考
- 更新
將
App
元件的內容 (App.razor
) 移至新增至專案根資料夾的新Routes
元件檔案 (Routes.razor
)。 將空白App.razor
檔案保留在專案的根資料夾中的應用程式中。將專案新增至
_Imports.razor
檔案,讓速記轉譯模式可供應用程式使用:@using static Microsoft.AspNetCore.Components.Web.RenderMode
將
_Host
頁面中的內容 (Pages/_Host.cshtml
) 移至空白的App.razor
檔案。 繼續對App
元件進行下列變更。注意
在下列範例中,專案的命名空間為
BlazorServerApp
。 調整命名空間以符合您的專案。從檔案頂端移除下列幾行:
- @page "/" - @using Microsoft.AspNetCore.Components.Web - @namespace BlazorServerApp.Pages - @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
將上述幾行取代為插入 IHostEnvironment 執行個體的行:
@inject IHostEnvironment Env
從
<base>
標籤的href
移除 tilde (~
),並以您應用程式的基底路徑取代:- <base href="~/" /> + <base href="/" />
移除
HeadOutlet
元件的元件標籤協助程式,並以HeadOutlet
元件取代它。移除下列程式碼:
- <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
將上述一行取代為以下內容:
<HeadOutlet @rendermode="InteractiveServer" />
移除
App
元件的元件標籤協助程式,並以Routes
元件取代它。移除下列程式碼:
- <component type="typeof(App)" render-mode="ServerPrerendered" />
將上述一行取代為以下內容:
<Routes @rendermode="InteractiveServer" />
注意
上述設定假設應用程式的元件採用互動式伺服器轉譯。 如需詳細資訊,包括如何採用靜態伺服器端轉譯 (SSR),請參閱 ASP.NET Core Blazor 轉譯模式。
移除錯誤 UI 的環境標記協助程式,並以下列 Razor 標記取代它們。
移除下列各行:
- <environment include="Staging,Production"> - An error has occurred. This application may no longer respond until reloaded. - </environment> - <environment include="Development"> - An unhandled exception has occurred. See browser dev tools for details. - </environment>
將上述幾行取代為以下內容:
@if (Env.IsDevelopment()) { <text> An unhandled exception has occurred. See browser dev tools for details. </text> } else { <text> An error has occurred. This app may no longer respond until reloaded. </text> }
將 Blazor 指令碼從
blazor.server.js
變更為blazor.web.js
:- <script src="_framework/blazor.server.js"></script> + <script src="_framework/blazor.web.js"></script>
刪除
Pages/_Host.cshtml
檔案。更新
Program.cs
:注意
在下列範例中,專案的命名空間為
BlazorServerApp
。 調整命名空間以符合您的專案。將
using
陳述式新增至專案命名空間檔案的頂端:using BlazorServerApp;
用
AddRazorComponents
取代AddServerSideBlazor
,並鏈結呼叫至AddInteractiveServerComponents
。移除下列程式碼:
- builder.Services.AddServerSideBlazor();
使用 Razor 元件和互動式伺服器元件服務來取代上一行。 呼叫
AddRazorComponents
預設會新增防偽服務 (AddAntiforgery
)。builder.Services.AddRazorComponents() .AddInteractiveServerComponents();
移除下列程式碼:
- app.MapBlazorHub();
將上一行取代為對
MapRazorComponents
的呼叫,提供App
元件做為根元件類型,並將鏈結呼叫新增至AddInteractiveServerRenderMode
:app.MapRazorComponents<App>() .AddInteractiveServerRenderMode();
移除下列程式碼:
- app.MapFallbackToPage("/_Host");
在呼叫
app.UseRouting
之後,將 Antiforgery 中介軟體新增至要求處理管線。 如果有對app.UseRouting
和app.UseEndpoints
發出呼叫,則對app.UseAntiforgery
的呼叫必須介於這兩者之間。 對app.UseAntiforgery
發出的呼叫必須在放置對app.UseAuthentication
和app.UseAuthorization
發出的呼叫之後。 無需新增防偽服務 (builder.Services.AddAntiforgery()
),因為它們是由前面介紹過的AddRazorComponents
自動新增的。app.UseAntiforgery();
如果 Blazor Server 應用程式已設定為停用預先轉譯,您可以繼續停用已更新應用程式的預先轉譯。 在
App
元件中,變更指派給HeadOutlet
和Routes
元件的@rendermode
Razor 指示詞屬性的值。變更
HeadOutlet
和Routes
元件的@rendermode
指示詞屬性值,以停用預先呈現:- @rendermode="InteractiveServer" + @rendermode="new InteractiveServerRenderMode(prerender: false)"
如需詳細資訊,請參閱 ASP.NET Core Blazor 轉譯模式。
更新 Blazor WebAssembly 應用程式
請遵循本文前三個章節的指導:
- 更新
global.json
中的 .NET SDK 版本 - 更新目標 Framework
- 更新套件參考
將裝載的 Blazor WebAssembly 應用程式轉換成 Blazor Web 應用程式
.NET 8 中支援 Blazor WebAssembly 應用程式,不需要變更任何程式碼。 使用下列指導將 ASP.NET Core 裝載的 Blazor WebAssembly 應用程式轉換成對等的 .NET 8 Blazor Web 應用程式,讓所有 新的 .NET 8 功能 都可供使用。
重要
本章節會著重在將 .NET 7 ASP.NET Core 裝載的 Blazor WebAssembly 應用程式轉換成 .NET 8 Blazor Web 應用程式所需的最小變更。 若要採用所有新的 Blazor Web 應用程式慣例,請遵循採用所有 Blazor Web 應用程式慣例一節中的指導。
請遵循本文前三個章節的指導:
- 更新
global.json
中的 .NET SDK 版本 - 更新目標 Framework
- 更新套件參考
重要
使用上述指導,更新解決方案的
.Client
、.Server
和.Shared
專案。- 更新
在
.Client
專案檔 (.csproj
) 中,新增下列 MSBuild 屬性:<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile> <StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
另外,在
.Client
專案檔中,移除Microsoft.AspNetCore.Components.WebAssembly.DevServer
套件參考:- <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer"... />
將檔案內容從
.Client/wwwroot/index.html
檔案移至在.Server
專案的根所建立的新App
元件檔案 (App.razor
)。 在您移動檔案的內容之後,請刪除index.html
檔案。將
.Client
專案中的App.razor
重新命名為Routes.razor
。在
Routes.razor
中,將AppAssembly
屬性值更新為typeof(Program).Assembly
。在
.Client
專案中,將項目新增至_Imports.razor
檔案,讓速記轉譯模式可供應用程式使用:@using static Microsoft.AspNetCore.Components.Web.RenderMode
製作
.Client
專案的_Imports.razor
檔案的複本,並將其新增至.Server
專案。對
App.razor
檔案進行下列變更:將網站的預設網站標題 (
<title>...</title>
) 取代為HeadOutlet
元件。 請記下網站標題以供稍後使用,並移除標題標籤和標題:- <title>...</title>
在您移除標題的位置,放置
HeadOutlet
元件,指派互動式 WebAssembly 轉譯模式 (已停用預先轉譯):<HeadOutlet @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />
變更 CSS 樣式組合:
- <link href="{CLIENT PROJECT ASSEMBLY NAME}.styles.css" rel="stylesheet"> + <link href="{SERVER PROJECT ASSEMBLY NAME}.styles.css" rel="stylesheet">
上面程式碼中的預留位置:
{CLIENT PROJECT ASSEMBLY NAME}
:用戶端專案組件名稱。 範例:BlazorSample.Client
{SERVER PROJECT ASSEMBLY NAME}
:伺服器專案組件名稱。 範例:BlazorSample.Server
找到下列
<div>...</div>
HTML 標記:- <div id="app"> - ... - </div>
使用互動式 WebAssembly 轉譯模式 (停用預先轉譯) 將上面的
<div>...</div>
HTML 標記取代為Routes
元件:<Routes @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />
將
blazor.webassembly.js
指令碼更新為blazor.web.js
:- <script src="_framework/blazor.webassembly.js"></script> + <script src="_framework/blazor.web.js"></script>
開啟
.Client
專案的配置檔案 (.Client/Shared/MainLayout.razor
),並新增具有網站預設標題 ({TITLE}
預留位置) 的PageTitle
元件:<PageTitle>{TITLE}</PageTitle>
從
.Client/Program.cs
移除下列行:- builder.RootComponents.Add<App>("#app"); - builder.RootComponents.Add<HeadOutlet>("head::after");
更新
.Server/Program.cs
:將 Razor 元件和互動式 WebAssembly 元件服務新增至專案。 透過對
AddInteractiveWebAssemblyComponents
的鏈結呼叫來呼叫AddRazorComponents
。 呼叫AddRazorComponents
預設會新增防偽服務 (AddAntiforgery
)。builder.Services.AddRazorComponents() .AddInteractiveWebAssemblyComponents();
將防偽中介軟體新增至要求處理管線。
放置下列程式碼:
- 在對
app.UseRouting
的呼叫之後。 - 如果有對
app.UseRouting
和app.UseEndpoints
發出呼叫,則對app.UseAntiforgery
的呼叫必須介於這兩者之間。 - 對
app.UseAntiforgery
的呼叫必須放置在對app.UseAuthorization
的呼叫之後 (如果有的話)。 - 無需新增防偽服務 (
builder.Services.AddAntiforgery()
),因為它們是由前面介紹過的AddRazorComponents
自動新增的。
app.UseAntiforgery();
移除下列程式碼:
- app.UseBlazorFrameworkFiles();
移除下列程式碼:
- app.MapFallbackToFile("index.html");
將上一行取代為對
MapRazorComponents
的呼叫,提供App
元件做為根元件類型,並將鏈結呼叫新增至AddInteractiveWebAssemblyRenderMode
和AddAdditionalAssemblies
:app.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof({CLIENT APP NAMESPACE}._Imports).Assembly);
在上述範例中,預留位置
{CLIENT APP NAMESPACE}
是.Client
專案的命名空間 (例如,HostedBlazorApp.Client
)。- 在對
從
.Server
專案執行解決方案:針對 Visual Studio,請確認 在執行應用程式時,已在 [方案總管] 中選取
.Server
專案。如果使用 .NET CLI,請從
.Server
專案的資料夾中執行專案。
更新服務和端點選項群組態
隨著 .NET 8 中 Blazor Web Apps 的發行,Blazor 服務和端點選項組態會隨著新 API 的引入而更新,以支援互動式元件服務和元件端點組態。
更新的組態指引出現在下列位置:
- 設定及讀取應用程式的環境:包含更新的指引,特別是在標題為 「讀取 Blazor Web 應用程式中的環境用戶端」一節。
- 伺服器端線路處理常式選項:涵蓋新的 Blazor-SignalR 線路和中樞選項組態。
- 從 JavaScript 呈現 Razor 元件:涵蓋使用 RegisterForJavaScript 進行動態元件註冊。
- Blazor 自訂元素: Blazor Web 應用程式註冊:涵蓋使用
RegisterCustomElement
進行根元件自訂元素註冊。 - Blazor WebAssembly 資產的前置詞:涵蓋對指示 Blazor WebAssembly 資產前置詞的路徑字串的控制。
- 暫時重新導向 URL 有效性持續期間:涵蓋對 Blazor 伺服器端呈現發出的暫時重新導向 URL 的資料保護有效性存留期的控制。
- 詳細錯誤:涵蓋啟用 Razor 元件伺服器端呈現的詳細錯誤。
- 預先呈現組態:預設會對 Blazor Web Apps 啟用預先呈現。 如果您有需要應用程式停用預先呈現的特殊情況,請按一下此連結以取得如何停用預先呈現的指引。
- 表單繫結選項:涵蓋表單繫結選項設定。
使用 Yarp 路由因應措施卸除Blazor Server
如果您先前遵循在累加移轉中使用 Yarp 啟用 ASP.NET Core Blazor Server 支援中的指引,將 Blazor Server Yarp 移轉至 .NET 6 或 .NET 7 的應用程式,您可以反轉遵循本文指引時採取的因應措施步驟。 使用 Yarp 的 Blazor Server 路由和深層連結可在 .NET 8 中正確運作。
移轉配置元件中的 CascadingValue
元件
階層式參數不會跨轉譯模式界限傳遞資料,而且配置會在其他互動式應用程式中以靜態方式呈現。 因此,尋求在互動式轉譯元件中使用階層式參數的應用程式將無法層疊配置中的值。
有以下兩種移轉方式:
- (建議) 將狀態作為根層級的階層式值傳遞。 如需詳細資訊,請參閱根層級階層式值。
- 使用
CascadingValue
元件將路由器包裝在Routes
元件中,並讓Routes
元件以互動方式轉譯。 如需範例,請參閱CascadingValue
元件。
如需詳細資訊,請參閱階層式值/參數和轉譯模式界限。
移轉 BlazorEnableCompression
MSBuild 屬性
對於停用壓縮並以 .NET 7 或更早版本為目標但使用 .NET 8 SDK 建置的 Blazor WebAssembly 應用程式,BlazorEnableCompression
MSBuild 屬性已變更為 CompressionEnabled
:
<PropertyGroup>
- <BlazorEnableCompression>false</BlazorEnableCompression>
+ <CompressionEnabled>false</CompressionEnabled>
</PropertyGroup>
使用 .NET CLI publish 命令時,請使用新的屬性:
dotnet publish -p:CompressionEnabled=false
如需詳細資訊,請參閱以下資源:
將 <CascadingAuthenticationState>
元件移轉至階層式驗證狀態服務
在 .NET 7 或更早版本中,CascadingAuthenticationState 元件會圍繞 UI 樹狀結構的某些部分 (例如 Blazor Router) 進行包裝,以提供階層式驗證狀態:
<CascadingAuthenticationState>
<Router ...>
...
</Router>
</CascadingAuthenticationState>
在 .NET 8 中,不要使用 CascadingAuthenticationState 元件:
- <CascadingAuthenticationState>
<Router ...>
...
</Router>
- </CascadingAuthenticationState>
而是透過呼叫 Program
檔中的 AddCascadingAuthenticationState 來將階層式驗證狀態服務新增至服務集合:
builder.Services.AddCascadingAuthenticationState();
如需詳細資訊,請參閱以下資源:
- ASP.NET Core Blazor 驗證和授權文章
- 保護 ASP.NET Core 伺服器端 Blazor 應用程式
有關 HTTP 快取問題的新文章
我們已新增了一篇新文章,討論在主要版本之間升級 Blazor 應用程式時可能出現的一些常見 HTTP 快取問題,以及如何解決 HTTP 快取問題。
如需詳細資訊,請參閱在升級 ASP.NET Core Blazor 應用程式時避免 HTTP 快取問題 (英文)。
關於使用靜態伺服器端轉譯 (靜態 SSR) 的類別庫的新文章
我們已新增了一篇新文章,討論在 Razor 類庫 (RCL) 中使用靜態伺服器端轉譯 (靜態 SSR) 進行元件庫的撰寫。
如需詳細資訊,請參閱使用靜態伺服器端轉譯 (靜態 SSR) 的 ASP.NET Core Razor 類別庫 (RCL) (英文)。
從其他組件中探索元件
從 Blazor Server 應用程式移轉至 Blazor Web 應用程式時,如果應用程式使用其他組件 (例如元件類別庫) 中的可路由元件,請造訪 ASP.NET Core Blazor 路由傳送和導覽中的指引。
當參數從查詢字串中提供時卸除 [Parameter]
屬性
從查詢字串中提供參數時不再需要 [Parameter]
屬性:
- [Parameter]
[SupplyParameterFromQuery]
Blazor Server 指令碼後援原則授權
在 .NET 7 中,Blazor Server 指令碼 (blazor.server.js
) 是由靜態檔案中介軟體提供。 在 .NET 7 應用程式中,在對授權中介軟體 (UseAuthorization
) 的呼叫之前,在要求處理管線中放置對靜態檔案中介軟體 (UseStaticFiles
) 的呼叫足以為匿名使用者提供 Blazor 指令碼。
在 .NET 8 中,Blazor Server 指令碼是由自己的端點使用端點路由傳送來提供。 此變更是由 Fixed bug - Passing options to UseStaticFiles breaks Blazor Server (dotnet/aspnetcore
#45897) 引入的。
考慮一個多租用戶的場景,其中:
- 預設和後援原則的設定相同。
- 租用戶是使用要求路徑中的第一個區段 (例如
tld.com/tenant-name/...
) 解析的。 - 對租用戶端點的要求會透過額外的驗證配置 (此配置會將額外的身分識別新增至要求主體) 進行驗證。
- 後援授權原則具有透過額外身分識別檢查宣告的需求。
對 Blazor 指令碼檔 (blazor.server.js
) 的要求是在 /_framework/blazor.server.js
提供 (該檔案在架構中進行硬編碼)。 對該檔案的要求不會透過租用戶的額外驗證配置進行驗證,但仍會受到後援原則的質疑,這會導致傳回未經授權的結果。
此問題正在針對 MapRazorComponents broken with FallbackPolicy RequireAuthenticatedUser (dotnet/aspnetcore
51836) 中的新架構功能進行評估,目前已計劃於 2024 年 11 月在 .NET 9 的發行中解決。 在那個日期之前,您可以使用下列三種方法中的任何一種方法來暫時解決此問題:
不要使用後援原則。 在
_Imports.razor
檔案中套用[Authorize]
屬性,以將其套用至應用程式的所有元件。 針對非 Blazor 端點,請明確使用[Authorize]
或RequireAuthorization
。將
[AllowAnonymous]
新增至Program
檔案中的/_framework/blazor.server.js
端點:app.MapBlazorHub().Add(endpointBuilder => { if (endpointBuilder is RouteEndpointBuilder { RoutePattern: { RawText: "/_framework/blazor.server.js" } }) { endpointBuilder.Metadata.Add(new AllowAnonymousAttribute()); } });
註冊一個自訂
AuthorizationHandler
來檢查HttpContext
以允許/_framework/blazor.server.js
檔案通過。
Docker
更新 Docker 映像
針對使用 Docker 的應用程式,更新 DockerfileFROM
陳述式和指令碼。 使用包含 ASP.NET Core 8.0 執行階段的基底映像。 請考慮 ASP.NET Core 7.0 和 8.0 之間的下列 docker pull
命令差異:
- docker pull mcr.microsoft.com/dotnet/aspnet:7.0
+ docker pull mcr.microsoft.com/dotnet/aspnet:8.0
更新 Docker 連接埠
在 .NET 容器映像中設定的預設 ASP.NET Core 連接埠已從 80 更新為 8080。
已新增了新的 ASPNETCORE_HTTP_PORTS
環境變數,作為 ASPNETCORE_URLS
的更簡單替代方案。
如需詳細資訊,請參閱
檢閱中斷性變更
如需從 .NET Core .NET 7.0 到 8.0 的中斷性變更,請參閱 .NET 8 中的中斷性變更,其中包括 ASP.NET Core 和 Entity Framework Core 章節。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應