本文介绍如何使用浏览器开发人员工具和集成开发环境 (IDE) 调试 Blazor WebAssembly。
可以使用基于 Chromium 的浏览器 (Microsoft Edge/Chrome) 和 Firefox 中的浏览器开发人员工具调试 Blazor WebAssembly 应用。 还可以使用以下 IDE 调试应用:
Visual Studio
Visual Studio for Mac
Visual Studio Code
可用方案包括:
设置和删除断点。
在 IDE 中运行具有调试支持的应用。
单步执行代码。
在 IDE 中使用键盘快捷方式恢复代码执行。
在“局部变量”窗口中,观察局部变量的值。
请参阅调用堆栈,包括 JavaScript 和 .NET 之间的调用链。
使用
符号服务器
进行调试,由 Visual Studio 首选项配置。
目前,无法执行以下操作:
出现未经处理的异常时中断。
于应用启动期间在调试代理运行之前命中断点。 这包括
Program.cs
中的断点和组件的
OnInitialized{Async}
生命周期方法
中的断点,其中这些组件由请求自应用的第一页加载。
在非本地方案中调试(例如,
适用于 Linux 的 Windows 子系统 (WSL)
或
Visual Studio Codespaces
)。
在调试期间自动重新生成托管的 Blazor WebAssembly
解决方案
的后端
Server
应用,例如通过使用
dotnet watch run
运行应用。
从 Visual Studio 在 Firefox 中进行调试。
可以使用基于 Chromium 的浏览器 (Microsoft Edge/Chrome) 中的浏览器开发人员工具调试 Blazor WebAssembly 应用。 还可以使用以下 IDE 调试应用:
Visual Studio
Visual Studio for Mac
Visual Studio Code
可用方案包括:
设置和删除断点。
在 IDE 中运行具有调试支持的应用。
单步执行代码。
在 IDE 中使用键盘快捷方式恢复代码执行。
在“局部变量”窗口中,观察局部变量的值。
请参阅调用堆栈,包括 JavaScript 和 .NET 之间的调用链。
目前,无法执行以下操作:
出现未经处理的异常时中断。
于应用启动期间在调试代理运行之前命中断点。 这包括
Program.cs
中的断点和组件的
OnInitialized{Async}
生命周期方法
中的断点,其中这些组件由请求自应用的第一页加载。
在非本地方案中调试(例如,
适用于 Linux 的 Windows 子系统 (WSL)
或
Visual Studio Codespaces
)。
在调试期间自动重新生成托管的 Blazor WebAssembly
解决方案
的后端
Server
应用,例如通过使用
dotnet watch run
运行应用。
使用
符号服务器
进行调试。
调试需要以下浏览器的最新版本:
Google Chrome
Microsoft Edge
Firefox
调试需要以下浏览器的最新版本:
Google Chrome(默认)
Microsoft Edge
确保防火墙或代理不会阻止与调试代理(
NodeJS
进程)之间的通信。 有关详细信息,请参阅
防火墙配置
部分。
Visual Studio Code 用户需要
适用于 Visual Studio Code 的 C# 扩展
。
Visual Studio Code 用户需要以下扩展:
适用于 Visual Studio Code 的 C# 扩展
Blazor WASM 调试扩展
(使用适用于 Visual Studio Code 的 C# 扩展版本 1.23.9 或更高版本时)
在 VS Code 中打开项目后可能会收到通知,告诉你需要进行其他设置才能启用调试。 如果收到请求,请从 Visual Studio Marketplace 安装所需扩展。 若要检查是否已安装此扩展,请在菜单栏中依次打开“视图”>“扩展”,或选择“活动”边栏中的“扩展”图标。
Visual Studio for Mac 需要版本 8.8(内部版本 1532)或更高版本。 选择
Microsoft:Visual Studio for Mac
页面上的“下载 Visual Studio for Mac”按钮,安装最新版本的 Visual Studio for Mac。
当前不支持 macOS 上的 Apple Safari。
独立 Blazor WebAssembly:
Microsoft.AspNetCore.Components.WebAssembly.DevServer
:生成 Blazor 应用时要使用的开发服务器。 在内部调用
WebAssemblyNetDebugProxyAppBuilderExtensions.UseWebAssemblyDebugging
来添加中间件以在 Chromium 开发人员工具中调试 Blazor WebAssembly 应用。
托管 Blazor WebAssembly:
Client
项目:
Microsoft.AspNetCore.Components.WebAssembly.DevServer
:生成 Blazor 应用时要使用的开发服务器。 在内部调用
WebAssemblyNetDebugProxyAppBuilderExtensions.UseWebAssemblyDebugging
来添加中间件以在 Chromium 开发人员工具中调试 Blazor WebAssembly 应用。
Server
项目:
Microsoft.AspNetCore.Components.WebAssembly.Server
:引用共享浏览器调试主机的程序集的内部包 (
Microsoft.NETCore.BrowserDebugHost.Transport
)。
有关将包添加到 .NET 应用的指南,请参阅
包使用工作流(NuGet 文档)
中“安装和管理包”下的文章。 在
NuGet.org
中确认正确的包版本。
调试独立的 Blazor WebAssembly 应用
若要为现有 Blazor WebAssembly 应用启用调试,请更新启动项目中的
launchSettings.json
文件,使每个启动配置文件包含以下
inspectUri
属性:
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
更新后,launchSettings.json
文件应类似于以下示例:
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:50454",
"sslPort": 44399
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
"BlazorApp1.Server": {
"commandName": "Project",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
inspectUri
属性具有以下作用:
使 IDE 能够检测到该应用为 Blazor WebAssembly 应用。
指示脚本调试基础结构通过 Blazor 的调试代理连接到浏览器。
已启动的浏览器 (browserInspectUri
) 上 WebSocket 协议 (wsProtocol
)、主机 (url.hostname
)、端口 (url.port
) 和检查器 URI 的占位符值由框架提供。
Visual Studio
Visual Studio for Mac
使用基于 Chromium 的浏览器(如 Google Chrome 或 Microsoft Edge)进行调试时,可能会打开一个新的浏览器窗口,其中有单独的配置文件用于调试会话,而不是使用用户配置文件在现有浏览器窗口中打开一个标签页。 如果要求使用用户配置文件进行调试,请采用以下方法之一:
请在按 F5 开始调试之前,关闭所有打开的浏览器实例。
配置 Visual Studio,以通过用户配置文件启动浏览器。 有关此方法的详细信息,请参阅 VS 中的 Blazor WASM 调试功能使用单独的用户数据目录启动 Microsoft Edge (dotnet/aspnetcore #20915)。
不支持“启动时不调试” [Ctrl+F5 (Windows) 或 ⌘+F5 (macOS )]。 当应用以调试配置运行时,调试开销始终会导致性能的小幅下降。
在 Client 应用中,在 Pages/Counter.razor
中的 currentCount++;
行上设置断点。
在浏览器中,导航到 Counter
页,然后选择“单击此处”按钮以命中断点。
在 Visual Studio 中,检查“局部变量”窗口中 currentCount
字段的值。
按 F5 继续执行。
调试 Blazor WebAssembly 应用时,还可以调试服务器代码:
在 OnInitializedAsync 的“Pages/FetchData.razor
”页中设置断点。
在 Get
操作方法的 WeatherForecastController
中设置一个断点。
浏览到 Fetch Data
页,在 FetchData
组件中的首个断点向服务器发出 HTTP 请求前命中该断点。
按 F5 以继续执行,然后在服务器上命中 WeatherForecastController
中的断点。
再次按 F5 以继续执行,并查看浏览器中呈现的天气预报表。
在运行调试代理之前,在应用启动期间不会命中断点。 这包括 Program.cs
中的断点和组件的 OnInitialized{Async}
生命周期方法中的断点,其中这些组件由请求自应用的第一页加载。
调试独立 Blazor WebAssembly
有关在 .vscode
文件夹中配置 VS Code 资产的信息,请参阅用于 ASP.NET Core Blazor 的工具中的 Linux 操作系统指南。
在 VS Code 中打开独立 Blazor WebAssembly 应用。
可能会收到通知,告诉你需要进行其他设置才能启用调试:
需要进行其他设置才能调试 Blazor WebAssembly 应用程序。
如果收到通知,请执行以下操作:
确认是否已安装最新的适用于 Visual Studio Code 的 C# 扩展。 若要检查是否已安装此扩展,请在菜单栏中依次打开“视图”>“扩展”,或选择“活动”边栏中的“扩展”图标。
使用适用于 Visual Studio Code 的 C# 扩展版本 1.23.9 或更高版本时,请确认安装了最新的 Blazor WASM 调试扩展。 若要检查是否已安装此扩展,请在菜单栏中依次打开“视图”>“扩展”,或选择“活动”边栏中的“扩展”图标。
重载窗口。
请创建一个具有以下配置的 .vscode/launch.json
文件。 将 {PORT}
占位符替换为 Properties/launchSettings.json
中配置的端口:
"name": "Launch and Debug",
"type": "blazorwasm",
"request": "launch",
"url": "http://localhost:{PORT}"
如果应用位于工作区根目录的子文件夹中,请将当前工作目录 (cwd
) 属性与应用的路径一起包含在内。 在以下属性值中,将 {PATH}
占位符替换为应用的路径:
"cwd": "${workspaceFolder}/{PATH}"
在以下示例中,应用位于名为 blazorwasm
的子文件夹中:
"cwd": "${workspaceFolder}/blazorwasm"
使用 F5 键盘快捷方式或菜单命令启动调试。
不支持“启动时不调试” [Ctrl+F5 (Windows) 或 ⌘+F5 (macOS )]。 当应用以调试配置运行时,调试开销始终会导致性能的小幅下降。
此时会启动独立应用,并打开调试浏览器。
在 Client 应用中,在 Pages/Counter.razor
中的 currentCount++;
行上设置断点。
在浏览器中,导航到 Counter
页,然后选择“单击此处”按钮以命中断点。
在运行调试代理之前,在应用启动期间不会命中断点。 这包括 Program.cs
中的断点和组件的 OnInitialized{Async}
生命周期方法中的断点,其中这些组件由请求自应用的第一页加载。
调试托管 Blazor WebAssembly
有关在 .vscode
文件夹中配置 VS Code 资产以及在解决方案中放置 .vscode
文件夹的位置的指导,请参阅适用于 ASP.NET Core Blazor 的工具中的 Linux 操作系统指南。
此时仅支持浏览器调试。
无法在调试期间自动重新生成托管 Blazor WebAssembly解决方案的后端 Server 应用,例如通过使用 dotnet watch run
运行应用。
若要调试已发布的托管 Blazor WebAssembly 应用,请配置调试器支持 (DebuggerSupport
),并将输出符号复制到 Client 应用的项目文件中的 publish
目录 (CopyOutputSymbolsToPublishDirectory
):
<DebuggerSupport>true</DebuggerSupport>
<CopyOutputSymbolsToPublishDirectory>true</CopyOutputSymbolsToPublishDirectory>
默认情况下,发布一个应用会将前面的属性设置为 false
,从而禁用这些属性。
已发布的托管 Blazor WebAssembly 应用应该只在本地部署已发布资产时启用调试和复制输出符号。 在 DebuggerSupport
和 CopyOutputSymbolsToPublishDirectory
属性设置为 true
的情况下,不要*将已发布的应用部署到生产环境中。
有关在 .vscode
文件夹中配置 VS Code 资产以及在解决方案中放置 .vscode
文件夹的位置的指导,请参阅适用于 ASP.NET Core Blazor 的工具中的 Linux 操作系统指南。
.vscode/launch.json
文件将当前工作目录设置为 Server 项目的文件夹,对于托管的 Blazor WebAssembly解决方案,通常为 Server:
"cwd": "${workspaceFolder}/Server"
如果使用 Microsoft Edge 而不是 Google Chrome 进行调试,则 .vscode/launch.json
启动配置将设置 browser
属性:
"browser": "edge"
.vscode/tasks.json
文件将 Server 应用的项目文件路径添加到 args
下的 dotnet build
参数中。 在基于托管的 Blazor WebAssembly 项目模板的解决方案中,Server 项目的文件夹通常被命名为 Server。 下面的示例使用 Blazor-SignalR 教程的 Server 应用的项目文件,它的项目文件名为 BlazorWebAssemblySignalRApp.Server.csproj
:
"tasks": [
"label": "build",
"command": "dotnet",
"type": "shell",
"args": [
"${workspaceFolder}/Server/BlazorWebAssemblySignalRApp.Server.csproj",
Server 项目的 Properties/launchSettings.json
文件包含调试代理的 inspectUri
属性。 下面的示例将 Blazor-SignalR 教程的 Server 应用的启动配置文件命名为 BlazorWebAssemblySignalRApp.Server
:
"iisSettings": {
"profiles": {
"IIS Express": {
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"BlazorWebAssemblySignalRApp.Server": {
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
若要调试已发布的托管 Blazor WebAssembly 应用,请配置调试器支持 (DebuggerSupport
),并将输出符号复制到 Client 应用的项目文件中的 publish
目录 (CopyOutputSymbolsToPublishDirectory
):
<DebuggerSupport>true</DebuggerSupport>
<CopyOutputSymbolsToPublishDirectory>true</CopyOutputSymbolsToPublishDirectory>
默认情况下,发布一个应用会将前面的属性设置为 false
,从而禁用这些属性。
已发布的托管 Blazor WebAssembly 应用应该只在本地部署已发布资产时启用调试和复制输出符号。 在 DebuggerSupport
和 CopyOutputSymbolsToPublishDirectory
属性设置为 true
的情况下,不要*将已发布的应用部署到生产环境中。
附加到现有的调试会话
若要附加到正在运行的 Blazor 应用,请创建一个具有以下配置的 .vscode/launch.json
文件。 将 {URL}
占位符替换为运行应用的 URL:
"name": "Attach and Debug"
"type": "blazorwasm",
"request": "attach",
"url": "{URL}"
只有独立应用才支持附加到调试会话。 若要使用完整堆栈调试,必须从 VS Code 启动应用。
启动配置选项
blazorwasm
调试类型 (.vscode/launch.json
) 支持以下启动配置选项。
要在 Visual Studio for Mac 中调试 Blazor WebAssembly 应用,请按以下步骤执行:
创建新的托管 Blazor WebAssembly 应用。
按 ⌘+↩ 在调试器中运行应用。
不支持“启动时不调试”(⌥+⌘+↩)。 当应用以调试配置运行时,调试开销始终会导致性能的小幅下降。
Google Chrome 或 Microsoft Edge 必须是调试会话的选定浏览器。
在 Client 应用中,在 Pages/Counter.razor
中的 currentCount++;
行上设置断点。
在浏览器中,导航到 Counter
页,然后选择“单击此处”按钮以命中断点:
在 Visual Studio 中,检查“局部变量”窗口中 currentCount
字段的值。
按 ⌘+↩ 继续执行。
调试 Blazor WebAssembly 应用时,还可以调试服务器代码:
在 OnInitializedAsync 的“Pages/FetchData.razor
”页中设置断点。
在 Get
操作方法的 WeatherForecastController
中设置一个断点。
浏览到 Fetch Data
页,在 FetchData
组件中的首个断点向服务器发出 HTTP 请求前命中该断点。
按 ⌘+↩ 继续执行,然后在服务器上命中 WeatherForecastController
中的断点。
再次按 ⌘+↩ 以继续执行,并查看浏览器中呈现的天气预报表。
在运行调试代理之前,在应用启动期间不会命中断点。 这包括 Program.cs
中的断点和组件的 OnInitialized{Async}
生命周期方法中的断点,其中这些组件由请求自应用的第一页加载。
有关详细信息,请参阅使用 Visual Studio for Mac 进行调试。
在浏览器中调试
本部分中的指南适用于在 Windows 上运行的 Google Chrome 和 Microsoft Edge。
在开发环境中运行该应用的调试版本。
启动浏览器并导航到应用程序的 URL。
在浏览器中,尝试通过按 Shift+Alt+d 启动远程调试。
浏览器必须在已启用远程调试的情况下运行,而这并不是默认设置。 如果远程调试处于禁用状态,将呈现“无法找到可调试的浏览器选项卡”错误页,并且其中包含关于在调试端口打开的情况下启动浏览器的说明。 按照适用于你的浏览器的说明操作,接下来将打开一个新的浏览器窗口。 关闭上一个浏览器窗口。
片刻后,“源”选项卡显示 file://
节点中应用的 .NET 程序集的列表。
在组件代码(.razor
文件)和 C# 代码文件 (.cs
) 中,当代码执行时将命中你设置的断点。 命中断点后,正常单步执行代码 (F10) 或恢复代码执行 (F8)。
Blazor 提供调试代理,该代理实现 Chrome DevTools Protocol,并使用特定于 .NET 的信息扩展该协议。 按下调试键盘快捷方式后,Blazor 会将 Chrome 开发者工具指向代理。 代理连接到要调试的浏览器窗口(因此需要启用远程调试)。
使用 Firefox 进行调试
使用 Firefox 调试 Blazor WebAssembly 应用需要配置浏览器以进行远程调试,并通过 .NET WebAssembly 调试代理使用浏览器开发人员工具连接到浏览器。
目前不支持从 Visual Studio 在 Firefox 中进行调试。
若要在开发期间调试 Blazor WebAssembly 应用,请执行以下操作:
在 Firefox 中打开 Blazor WebAssembly 应用。
打开 Firefox Web 开发人员工具并转到 Console
选项卡。
当 Blazor WebAssembly 应用处于焦点时,键入调试命令 SHIFT+ALT+D。
按照控制台输出中的说明配置 Firefox 进行 Blazor WebAssembly 调试:
- 在 Firefox 中打开
about:config
。
- 启用
devtools.debugger.remote-enabled
。
- 启用
devtools.chrome.enabled
。
- 禁用
devtools.debugger.prompt-connection
。
- 通过在命令行界面中运行以下命令,关闭所有 Firefox 实例并重新打开启用了远程调试的 Firefox:
firefox --start-debugger-server 6000 -new-tab about:debugging
。
- 在新的 Firefox 实例中,使
about:debugging
选项卡保持打开状态,并在新的浏览器选项卡中打开 Blazor WebAssembly 应用。
- 键入 SHIFT+Alt 打开 Firefox Web 开发人员工具并连接到 Firefox 浏览器实例。
- 在
Debugger
选项卡中,在 file://
节点下打开要调试的应用源文件,并设置断点。 例如,在 Counter
组件 (Pages/Counter.razor
) 的 IncrementCount
方法中设置断点。
- 导航到
Counter
组件页 (/counter
) 并选择计数器按钮以命中断点。
浏览器源映射
浏览器源映射允许浏览器将编译后的文件映射回其原始源文件,并且通常用于客户端调试。 但是,Blazor 当前不直接将 C# 映射到 JavaScript/WASM。 相反,Blazor 在浏览器中进行 IL 解释,因此源映射不相关。
防火墙配置
如果防火墙阻止与调试代理之间的通信,则创建允许浏览器与 NodeJS
进程之间进行通信的防火墙例外规则。
必须谨慎修改防火墙配置,以避免造成安全漏洞。 仔细应用安全指南、遵循最佳安全实践,并遵守防火墙制造商发出的警告。
允许与 NodeJS
进程之间的开放式通信:
- 根据防火墙的功能和配置,打开节点服务器的任何连接。
- 可能会因网络而有风险。
- 仅建议在开发人员计算机上使用。
如果可能,只允许与受信任的网络或专用网络上的 NodeJS
进程之间的开放式通信。
有关 Windows 防火墙配置指南,请参阅创建入站程序或服务规则。 有关详细信息,请参阅 Windows 防火墙文档集中的具有高级安全性的 Windows Defender 防火墙和相关文章。
如果遇到错误,以下提示可能有所帮助:
- 在“调试程序”选项卡中,在浏览器中打开开发人员工具。 在控制台中,执行
localStorage.clear()
以删除所有断点。
- 确认你已安装并信任 ASP.NET Core HTTPS 开发证书。 有关详细信息,请参阅在 ASP.NET Core 中强制使用 HTTPS。
- Visual Studio 要求在“工具”>“选项”>“调试”>“常规”中选择“对 ASP.NET 启用 JavaScript 调试(Chrome、Edge 和 IE)”选项。 这是 Visual Studio 的默认设置。 如果调试不起作用,请确认已选中该选项。
- 如果你的环境使用 HTTP 代理,请确保在代理绕过设置中包含
localhost
。 这可以通过在以下二者之一中设置 NO_PROXY
环境变量来实现:
- 项目的
launchSettings.json
文件。
- 在将其应用于所有应用时所在的用户或系统环境变量级别。 使用环境变量时,请重新启动 Visual Studio 以使更改生效。
- 确保防火墙或代理不会阻止与调试代理(
NodeJS
进程)之间的通信。 有关详细信息,请参阅防火墙配置部分。
OnInitialized{Async}
中的未命中断点
Blazor 框架的调试代理需要一小段时间才能启动,因此 OnInitialized{Async}
生命周期方法中的断点可能不会命中。 建议在方法主体开头添加延迟,以便在命中断点之前,为调试代理指定一段时间来启动。 你可以根据 if
编译器指令包括延迟,以确保应用的发布版本不存在延迟。
OnInitialized:
protected override void OnInitialized()
#if DEBUG
Thread.Sleep(10000);
#endif
OnInitializedAsync:
protected override async Task OnInitializedAsync()
#if DEBUG
await Task.Delay(10000);
#endif
Visual Studio (Windows) 超时
如果 Visual Studio 引发了调试适配器启动因已达到超时而失败的异常,可使用注册表设置调整超时:
VsRegEdit.exe set "<VSInstallFolder>" HKCU JSDebugger\Options\Debugging "BlazorTimeoutInMilliseconds" dword {TIMEOUT}
前述命令中的 {TIMEOUT}
占位符以毫秒为单位。 例如, 1 分钟指定为 60000
。