调试 ASP.NET Core 应用

注意

此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本

重要

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。

对于当前版本,请参阅此文的 .NET 8 版本

本文介绍如何使用浏览器开发人员工具或集成开发环境 (IDE) 调试 Blazor,包括调试 Blazor WebAssembly 应用。

可以在 Visual Studio 和 Visual Studio Code 中调试 Blazor Web 应用。

可对 Blazor WebAssembly 应用进行调试:

  • 在 Visual Studio 或 Visual Studio Code 中。
  • 在基于 Chromium 的浏览器中使用浏览器开发人员工具,包括 Microsoft Edge、Google Chrome 和 Firefox。

可应用 Blazor WebAssembly 调试的方案包括:

  • 设置和删除断点。
  • 在 IDE 中运行具有调试支持的应用。
  • 单步执行代码。
  • 在 IDE 中使用键盘快捷方式恢复代码执行。
  • 在“局部变量”窗口中,观察局部变量的值。
  • 请参阅调用堆栈,包括 JavaScript 和 .NET 之间的调用链。
  • 使用符号服务器进行调试,由 Visual Studio 首选项配置。

不支持的方案包括:

可以在 IDE、Visual Studio 和 Visual Studio Code 中调试 Blazor Server 应用。

可对 Blazor WebAssembly 应用进行调试:

  • 在 Visual Studio 或 Visual Studio Code 中。
  • 在基于 Chromium 的浏览器中使用浏览器开发人员工具,包括 Microsoft Edge 和 Google Chrome。

不支持应用的方案 Blazor WebAssembly 包括:

  • 设置和删除断点。
  • 在 IDE 中运行具有调试支持的应用。
  • 单步执行代码。
  • 在 IDE 中使用键盘快捷方式恢复代码执行。
  • 在“局部变量”窗口中,观察局部变量的值。
  • 请参阅调用堆栈,包括 JavaScript 和 .NET 之间的调用链。
  • 在非本地方案中调试(例如,适用于 Linux 的 Windows 子系统 (WSL)Visual Studio Codespaces)。
  • 使用符号服务器进行调试。

可以在 IDE、Visual Studio 和 Visual Studio Code 中调试 Blazor Server 应用。

可对 Blazor WebAssembly 应用进行调试:

  • 在 Visual Studio 或 Visual Studio Code 中。
  • 在基于 Chromium 的浏览器中使用浏览器开发人员工具,包括 Microsoft Edge 和 Google Chrome。

不支持应用的方案 Blazor WebAssembly 包括:

  • 设置和删除断点。
  • 在 IDE 中运行具有调试支持的应用。
  • 单步执行代码。
  • 在 IDE 中使用键盘快捷方式恢复代码执行。
  • 在“局部变量”窗口中,观察局部变量的值。
  • 请参阅调用堆栈,包括 JavaScript 和 .NET 之间的调用链。
  • 于应用启动期间在调试代理运行之前命中断点。 这包括 Program 文件中的断点和组件的 OnInitialized{Async} 生命周期方法中的断点,并通过从应用请求的第一页来加载。
  • 在非本地方案中调试(例如,适用于 Linux 的 Windows 子系统 (WSL)Visual Studio Codespaces)。
  • 使用符号服务器进行调试。

先决条件

本部分介绍调试的先决条件。

浏览器先决条件

以下浏览器的最新版本:

  • Google Chrome
  • Microsoft Edge
  • Firefox(仅限浏览器开发人员工具)

调试需要以下浏览器的最新版本:

  • Google Chrome(默认)
  • Microsoft Edge

确保防火墙或代理不会阻止与调试代理(NodeJS 进程)之间的通信。 有关详细信息,请参阅防火墙配置部分。

注意

当前不支持 macOS 上的 Apple Safari。

IDE 先决条件

需要最新版本的 Visual Studio 或 Visual Studio Code。

Visual Studio Code 必备条件

Visual Studio Code 需要适用于 Visual Studio Code 的 C# 开发工具包VS Code中的 C# 入门)。 在 Visual Studio Code Extensions Marketplace 中,使用“c# dev kit”筛选扩展列表以查找扩展:

Visual Studio Code 扩展市场中的 C# 开发工具包

安装 C# 开发工具包会自动安装以下附加扩展:

如果显示警告或错误,可以创建问题(microsoft/vscode-dotnettools GitHub 存储库)并在其中描述相关问题。

应用配置必备条件

此小节中的指南适用于客户端调试。

打开启动项目的 Properties/launchSettings.json 文件。 确认文件 profiles 节点的每个启动配置文件中是否存在以下 inspectUri 属性。 如果不存在以下属性,请将其添加到每个配置文件:

"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"

inspectUri 属性具有以下作用:

  • 使 IDE 能够检测到该应用为 Blazor 应用。
  • 指示脚本调试基础结构通过 Blazor 的调试代理连接到浏览器。

已启动的浏览器 (browserInspectUri) 上 WebSocket 协议 (wsProtocol)、主机 (url.hostname)、端口 (url.port) 和检查器 URI 的占位符值由框架提供。

Blazor Web 应用:Microsoft.AspNetCore.Components.WebAssembly.Server:引用共享浏览器调试主机的程序集的内部包 (Microsoft.NETCore.BrowserDebugHost.Transport)。

Blazor Server:Microsoft.AspNetCore.Components.WebAssembly.Server:引用共享浏览器调试主机的程序集的内部包 (Microsoft.NETCore.BrowserDebugHost.Transport)。

独立 Blazor WebAssembly:Microsoft.AspNetCore.Components.WebAssembly.DevServer:生成 Blazor 应用时要使用的开发服务器。 在内部调用 WebAssemblyNetDebugProxyAppBuilderExtensions.UseWebAssemblyDebugging 来添加中间件以在 Chromium 开发人员工具中调试 Blazor WebAssembly 应用。

托管 Blazor WebAssembly:

注意

有关将包添加到 .NET 应用的指南,请参阅包使用工作流(NuGet 文档)中“安装和管理包”下的文章。 在 NuGet.org 中确认正确的包版本。

在 IDE 中调试 Blazor Web 应用

本部分中的示例假定你已创建了一个 Blazor Web 应用,其交互呈现模式为自动(服务器和 WebAssembly)和每个组件交互位置。

  1. 打开应用。
  2. 在客户端项目 (.Client) 的 Counter 组件 (Pages/Counter.razor) 的 currentCount++; 行上设置一个断点。
  3. F5 在调试器中运行应用。
  4. 在浏览器中,导航到 /counter 处的 Counter 页面。 等待几秒钟,让调试代理加载并运行。 选择“单击我”按钮以命中断点
  5. 在 Visual Studio 中,检查“局部变量”窗口中 currentCount 字段的值。
  6. F5 继续执行。

在静态呈现和交互式呈现的服务器端组件中,也可能在服务器项目中遇到断点。

  1. 停止调试器。

  2. 将以下组件添加到服务器应用。 该组件应用交互式服务器呈现模式(InteractiveServer)。

    Components/Pages/Counter2.razor

    @page "/counter-2"
    @rendermode InteractiveServer
    
    <PageTitle>Counter 2</PageTitle>
    
    <h1>Counter 2</h1>
    
    <p role="status">Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  3. Counter2 组件中的 currentCount++; 行上设置断点。

  4. F5 在调试器中运行应用。

  5. 在浏览器中,导航到 /counter-2 处的 Counter2 页面。 等待几秒钟,让调试代理加载并运行。 选择“单击我”按钮以命中断点

  6. F5 继续执行。

在运行调试代理之前,在应用启动期间不会命中断点。 这包括 Program 文件中的断点和组件的 OnInitialized{Async} 生命周期方法中的断点,并通过从应用请求的第一页来加载。

在 IDE 中调试 Blazor Server 应用

  1. 打开应用。
  2. Counter 组件 (Pages/Counter.razor) 中的 currentCount++; 行上设置一个断点。
  3. F5 在调试器中运行应用。
  4. 在浏览器中,导航到 /counter 处的 Counter 页面。 等待几秒钟,让调试代理加载并运行。 选择“单击我”按钮以命中断点
  5. 在 Visual Studio 中,检查“局部变量”窗口中 currentCount 字段的值。
  6. F5 继续执行。

在运行调试代理之前,在应用启动期间不会命中断点。 这包括 Program 文件中的断点和组件的 OnInitialized{Async} 生命周期方法中的断点,并通过从应用请求的第一页来加载。

在 IDE 中调试 Blazor WebAssembly 应用

  1. 打开应用。
  2. Counter 组件 (Pages/Counter.razor) 中的 currentCount++; 行上设置一个断点。
  3. F5 在调试器中运行应用。
  4. 在浏览器中,导航到 /counter 处的 Counter 页面。 等待几秒钟,让调试代理加载并运行。 选择“单击我”按钮以命中断点
  5. 在 Visual Studio 中,检查“局部变量”窗口中 currentCount 字段的值。
  6. F5 继续执行。

在运行调试代理之前,在应用启动期间不会命中断点。 这包括 Program 文件中的断点和组件的 OnInitialized{Async} 生命周期方法中的断点,并通过从应用请求的第一页来加载。

调试器支持

当使用 <DebuggerSupport>{VALUE}</DebuggerSupport> 启用调试程序支持时,将为运行时启用调试,其中 {VALUE} 占位符为 truefalse

默认情况下,Blazor 框架禁用对所有非调试配置的调试程序支持。 若要为非调试配置启用调试程序支持,请将 <DebuggerSupport> 属性添加到应用的项目文件中。

在以下示例中,为自定义“DebugCustom”配置启用调试程序支持:

<DebuggerSupport Condition="'$(Configuration)' == 'DebugCustom'">true</DebuggerSupport>

有关详细信息,请参阅Blazor WebAssembly 自定义调试程序配置 (dotnet/runtime #96239)

在 IDE 中调试托管 Blazor WebAssembly 应用

  1. 在“解决方案资源管理器”中选择 Server 项目后,按 F5 在调试器中运行应用。

    使用基于 Chromium 的浏览器(如 Google Chrome 或 Microsoft Edge)进行调试时,可能会打开一个新的浏览器窗口,其中有单独的配置文件用于调试会话,而不是使用用户配置文件在现有浏览器窗口中打开一个标签页。 如果要求使用用户配置文件进行调试,请采用以下方法之一:

  2. Client 项目中,在 Counter 组件 (Pages/Counter.razor)的 currentCount++; 行上设置一个断点。

  3. 在浏览器中,导航到 /counter 处的 Counter 页面。 等待几秒钟,让调试代理加载并运行。 选择“单击我”按钮以命中断点

  4. 在 Visual Studio 中,检查“局部变量”窗口中 currentCount 字段的值。

  5. F5 继续执行。

还可以在 Server 项目中调试服务器代码:

  1. OnInitializedAsync 的“Pages/FetchData.razor”页中设置断点。
  2. Get 操作方法的 WeatherForecastController 中设置一个断点。
  3. 浏览到 Fetch Data 页,在 FetchData 组件中的首个断点向服务器发出 HTTP 请求前命中该断点。
  4. F5 以继续执行,然后在服务器上命中 WeatherForecastController 中的断点。
  5. 再次按 F5 以继续执行,并查看浏览器中呈现的天气预报表。

在运行调试代理之前,在应用启动期间不会命中断点。 这包括 Program 文件中的断点和组件的 OnInitialized{Async} 生命周期方法中的断点,并通过从应用请求的第一页来加载。

不支持“启动时不调试” [Ctrl+F5 (Windows) 或 +F5 (macOS )]。 当应用以调试配置运行时,调试开销始终会导致性能的小幅下降。

附加到现有 Visual Studio Code 调试会话

若要附加到一个正在运行的 Blazor 应用,可打开 .vscode/launch.json 文件,并将 {URL} 占位符替换为应用运行时所在的 URL:

{
  "name": "Attach and Debug",
  "type": "blazorwasm",
  "request": "attach",
  "url": "{URL}"
}

Visual Studio Code 启动选项

blazorwasm 调试类型 (.vscode/launch.json) 支持下表中的启动配置选项。

选项 说明
browser 要为调试会话启动的浏览器。 设置为 edgechrome。 默认为 edge
cwd 要在其中启动应用的工作目录。
request 使用 launch 启动调试会话并将其附加到 Blazor WebAssembly 应用,或使用 attach 将调试会话附加到已运行的应用。
timeout 等待调试会话附加完成的毫秒数。 默认值为 30,000 毫秒(30 秒)。
trace 用于从 JS 调试程序生成日志。 设置为 true 即可生成日志。
url 调试时要在浏览器中打开的 URL。
webRoot 指定 Web 服务器的绝对路径。 如果应用是从子路由中提供的,则应设置它。

下表中的其他选项仅适用于托管的 Blazor WebAssembly 应用

选项 说明
env 要提供给已启动进程的环境变量。 仅当 hosted 设置为 true 时才适用。
hosted 如果要启动和调试托管的 Blazor WebAssembly 应用,则必须设置为 true
program 为运行托管应用的服务器而对可执行文件进行的引用。 如果 hostedtrue,则必须设置它。

使用 Google Chrome 或 Microsoft Edge 调试 Blazor WebAssembly

本部分中的指南涉及在 中调试 Blazor WebAssembly 应用。

  • 在 Windows 或 macOS 上运行的 Google Chrome。
  • 在 Windows 上运行的 Microsoft Edge。
  1. 使用 dotnet run 在命令行界面中运行该应用。

  2. 启动浏览器并导航到应用程序的 URL。

  3. 按以下键启动远程调试:

    • 在 Windows 上按 Shift+Alt+d
    • 在 macOS 上按 Shift++d

    浏览器必须在已启用远程调试的情况下运行,而这并不是默认设置。 如果远程调试处于禁用状态,将呈现“无法找到可调试的浏览器选项卡”错误页,并且其中包含关于在调试端口打开的情况下启动浏览器的说明。 按照浏览器相关说明操作。

    按照说明启用远程调试后,应用将在新的浏览器窗口中打开。 要开始远程调试,请在新的浏览器窗口中按热键组合:

    • 在 Windows 上按 Shift+Alt+d
    • 在 macOS 上按 Shift++d

    这会打开新的窗口开发人员工具浏览器选项卡,显示应用的虚影图像。

    注意

    如果按照说明打开启用了远程调试的新浏览器选项卡,可以关闭原始浏览器窗口,将第二个窗口保持在打开状态,其中第一个标签运行应用,第二个选项卡运行调试程序。

  4. 片刻后,“源”选项卡会显示应用的 .NET 程序集和页面的列表

  5. 打开 file:// 节点。 在组件代码(.razor 文件)和 C# 代码文件(.cs)it中,在应用的浏览器选项卡(启动远程调试后打开的初始选项卡)中执行代码时,将遇到你设置的断点。 命中断点后,在“调试”选项卡中正常单步执行代码 (F10) 或恢复代码执行 (F8)。

对于基于 Chromium 的浏览器调试,Blazor 提供调试代理,该代理实现 Chrome DevTools 协议,并使用特定于 .NET 的信息扩展该协议。 按下调试键盘快捷方式后,Blazor 会将 Chrome 开发者工具指向代理。 代理连接到要调试的浏览器窗口(因此需要启用远程调试)。

使用 Firefox 调试 Blazor WebAssembly 应用

本部分中的指南涉及在 Windows 上运行的 Firefox 中调试 Blazor WebAssembly 应用。

使用 Firefox 调试 Blazor WebAssembly 应用需要配置浏览器以进行远程调试,并通过 .NET WebAssembly 调试代理使用浏览器开发人员工具连接到浏览器。

注意

目前不支持从 Visual Studio 在 Firefox 中进行调试。

若要在开发期间调试 Blazor WebAssembly 应用,请执行以下操作:

  1. 配置 Firefox:
    • 在新的浏览器选项卡中打开 about:config。读取并消除出现的警告。
    • 通过将值设置为 True 来启用 devtools.debugger.remote-enabled
    • 通过将值设置为 True 来启用 devtools.chrome.enabled
    • 通过将值设置为 False 来禁用 devtools.debugger.prompt-connection
  2. 关闭所有 Firefox 实例。
  3. 使用 dotnet run 在命令行界面中运行该应用。
  4. 重新启动 Firefox 浏览器并导航到应用。
  5. 在新的浏览器选项卡中打开 about:debugging。让此选项卡保持打开状态
  6. 返回到运行应用的选项卡。 按 Shift+Alt+d 开始远程调试。
  7. Debugger 选项卡中,在 file:// 节点下打开要调试的应用源文件,并设置断点。 在 Counter 组件 (Pages/Counter.razor) 的 IncrementCount 方法中,在 currentCount++; 行上设置断点。
  8. 导航到应用浏览器选项卡中的 Counter 组件页 (/counter),并选择计数器按钮以命中断点。
  9. F5 继续在“调试”选项卡中执行。

出现未经处理的异常时中断

默认情况下,调试程序不会因未处理的异常而中断,因为 Blazor 会捕获未由开发人员代码处理的异常。

若要中断未经处理的异常,请执行以下操作:

  • 在 Visual Studio 中打开调试程序的异常设置(“调试”>“Windows”>“异常设置”)。
  • 设置以下“JavaScript 异常”设置:
    • 所有异常
    • 未捕获的异常

浏览器源映射

浏览器源映射允许浏览器将编译后的文件映射回其原始源文件,并且通常用于客户端调试。 但是,Blazor 当前不直接将 C# 映射到 JavaScript/WASM。 相反,Blazor 在浏览器中进行 IL 解释,因此源映射不相关。

防火墙配置

如果防火墙阻止与调试代理之间的通信,则创建允许浏览器与 NodeJS 进程之间进行通信的防火墙例外规则。

警告

必须谨慎修改防火墙配置,以避免造成安全漏洞。 仔细应用安全指南、遵循最佳安全实践,并遵守防火墙制造商发出的警告。

允许与 NodeJS 进程之间的开放式通信:

  • 根据防火墙的功能和配置,打开节点服务器的任何连接。
  • 可能会因网络而有风险。
  • 仅建议在开发人员计算机上使用。

如果可能,只允许与受信任的网络或专用网络上的 NodeJS 进程之间的开放式通信。

有关 Windows 防火墙配置指南,请参阅创建入站程序或服务规则。 有关详细信息,请参阅 Windows 防火墙文档集中的具有高级安全性的 Windows Defender 防火墙和相关文章。

疑难解答

如果遇到错误,以下提示可能有所帮助:

  • 删除断点:
    • Google Chrome:在“调试程序”选项卡中,在浏览器中打开开发人员工具。 在控制台中,执行 localStorage.clear() 以删除所有断点。
    • Microsoft Edge:在“应用程序”选项卡中,打开“本地存储”。 右键单击该网站,然后选择“清除”
  • 确认你已安装并信任 ASP.NET Core HTTPS 开发证书。 有关详细信息,请参阅在 ASP.NET Core 中强制使用 HTTPS
  • Visual Studio 要求在“工具”>“选项”>“调试”>“常规”中选择“对 ASP.NET 启用 JavaScript 调试(Chrome 和 Edge)”选项。 这是 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