使用文件观察程序开发 ASP.NET 核心应用

作者: 里克·安德森维克多·赫杜加奇

dotnet watch 是一个工具,可在源文件更改时运行 .NET CLI 命令。 例如,文件更改可以触发编译、测试执行或部署。

本教程使用具有两个终结点的现有 Web API:一个终结点返回总和,一个返回一个产品。 产品方法有一个 bug,本教程对此进行了修复。

下载 示例应用。 它由两个项目组成: WebApp (ASP.NET 核心 Web API)和 WebAppTests(Web API 的单元测试)。

在命令行界面中,导航到 WebApp 文件夹。 运行下面的命令:

dotnet run

注释

可用于 dotnet run --project <PROJECT> 指定要运行的项目。 例如,从示例应用的根目录运行 dotnet run --project WebApp 也会运行 WebApp 项目。

控制台输出显示类似于以下内容的消息(指示应用正在运行并等待请求):

$ dotnet run
Hosting environment: Development
Content root path: C:/Docs/aspnetcore/tutorials/dotnet-watch/sample/WebApp
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

在 Web 浏览器中导航到 http://localhost:<port number>/api/math/sum?a=4&b=5。 应该能看到 9 的结果。

进入产品 API (http://localhost:<port number>/api/math/product?a=4&b=5)。 它返回 9,而不是 20 如预期的那样。 本教程稍后将修复此问题。

向项目中添加 dotnet watch

dotnet watch 文件监视器工具包含在 .NET Core SDK 版本 2.1.300 中。 使用早期版本的 .NET Core SDK 时,需要执行以下步骤。

  1. .csproj 文件中添加 Microsoft.DotNet.Watcher.Tools 包引用。

    <ItemGroup>
        <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
    </ItemGroup>
    
  2. 运行以下命令,安装 Microsoft.DotNet.Watcher.Tools 包:

    dotnet restore
    

使用 dotnet watch 运行 .NET CLI 命令

可以运行任何 .NET CLI 命令 使用 dotnet watch。 例如:

指令 带有监视功能的命令
dotnet run dotnet watch run
dotnet run -f netcoreapp3.1 dotnet watch run -f netcoreapp3.1
使用命令行参数运行 dotnet 程序:dotnet run -f netcoreapp3.1 -- --arg1 dotnet watch run -f netcoreapp3.1 -- --arg1
dotnet test dotnet watch 测试

WebApp 文件夹中运行dotnet watch run。 控制台输出指示 watch 已启动。

dotnet watch run在 Web 应用上运行会启动一个浏览器,该浏览器在准备就绪后导航到应用的 URL。 dotnet watch 通过读取应用程序的控制台输出,并等待WebHost显示的就绪消息来完成此操作。

dotnet watch 检测到对受监视文件的更改时,它会刷新浏览器。 为此,监视命令会将中间件注入应用,以修改应用创建的 HTML 响应。 中间件将 JavaScript 脚本块添加到页面中,使 dotnet watch 能够指示浏览器刷新。 目前,对所有受监视文件(包括静态内容,例如 .html 文件和 .css 文件)的更改会导致应用被重新生成。

dotnet watch:

  • 仅监视默认情况下影响生成的文件。
  • 任何其他被监视的文件(通过配置)仍然会触发构建过程。

有关配置的详细信息,请参阅本文档中的 dotnet-watch 配置

注释

可用于 dotnet watch --project <PROJECT> 指定要监视的项目。 例如,从示例应用的根目录运行 dotnet watch --project WebApp run 也会运行并监视 WebApp 项目。

使用 dotnet watch 进行更改

请确保 dotnet watch 正在运行。

修复Product方法中的MathController.cs bug,使其返回乘积而不是总和。

public static int Product(int a, int b)
{
    return a * b;
}

保存文件。 控制台输出指示 dotnet watch 检测到文件更改并重新启动了应用。

验证 http://localhost:<port number>/api/math/product?a=4&b=5 是否返回正确的结果。

使用 dotnet watch 运行测试

  1. MathController.csProduct 方法改回返回总和。 保存文件。

  2. 在命令行界面中,导航到 WebAppTests 文件夹。

  3. 运行 dotnet 还原

  4. 运行 dotnet watch test。 其输出表明测试失败,观察者正在等待文件更改。

    Total tests: 2. Passed: 1. Failed: 1. Skipped: 0.
    Test Run Failed.
    
  5. Product修复方法代码,使其返回产品。 保存文件。

dotnet watch 检测文件更改并重新运行测试。 控制台输出显示测试已通过。

自定义要监视的文件列表

默认情况下, dotnet-watch 跟踪与以下 glob 模式匹配的所有文件:

  • **/*.cs
  • *.csproj
  • **/*.resx
  • 内容文件:wwwroot/**, **/*.config, **/*.json

可以通过编辑 .csproj 文件将更多项目添加到监视列表中。 可以单独或通过使用 glob 模式来指定项。

<ItemGroup>
    <!-- extends watching group to include *.js files -->
    <Watch Include="**\*.js" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
</ItemGroup>

取消要监视的文件

dotnet-watch 可配置为忽略其默认设置。 若要忽略特定文件,请将 Watch="false" 属性添加到文件中项的定义 .csproj

<ItemGroup>
    <!-- exclude Generated.cs from dotnet-watch -->
    <Compile Include="Generated.cs" Watch="false" />

    <!-- exclude Strings.resx from dotnet-watch -->
    <EmbeddedResource Include="Strings.resx" Watch="false" />

    <!-- exclude changes in this referenced project -->
    <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" Watch="false" />
</ItemGroup>
<ItemGroup>
     <!-- Exclude all Content items from being watched. -->
    <Content Update="@(Content)" Watch="false" />
</ItemGroup>

定制手表项目

dotnet-watch 不限于 C# 项目。 可以创建自定义监控项目以应对不同的情况。 请考虑以下项目布局:

  • 测试/
    • UnitTests/UnitTests.csproj
    • IntegrationTests/IntegrationTests.csproj

如果目标是监视这两个项目,请创建一个配置为监视这两个项目的自定义项目文件:

<Project>
    <ItemGroup>
        <TestProjects Include="**\*.csproj" />
        <Watch Include="**\*.cs" />
    </ItemGroup>

    <Target Name="Test">
        <MSBuild Targets="VSTest" Projects="@(TestProjects)" />
    </Target>

    <Import Project="$(MSBuildExtensionsPath)\Microsoft.Common.targets" />
</Project>

若要开始在两个项目上监视文件,请更改为 测试 文件夹。 请执行以下命令:

dotnet watch msbuild /t:Test

当任一测试项目中的任何文件更改时,VSTest 将执行。

dotnet-watch 配置

某些配置选项可以传递给 dotnet watch 环境变量。 可用的变量包括:

设置 DESCRIPTION
DOTNET_USE_POLLING_FILE_WATCHER 如果设置为“1”或“true”,dotnet watch 将使用轮询文件监视器,而不是 CoreFx 的 FileSystemWatcher。 在监视网络共享或 Docker 装载卷上的文件时使用。
DOTNET_WATCH_SUPPRESS_MSBUILD_INCREMENTALISM 默认情况下,dotnet watch 通过避免执行某些操作(例如运行还原或在每次文件更改时重新评估监视的文件集)来优化构建。 如果设置为“1”或“true”,则禁用这些优化。
DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER dotnet watch run尝试启动浏览器,用于在launchSettings.json中配置了launchBrowser的 Web 应用。 如果设置为“1”或“true”,则会取消此行为。
DOTNET_WATCH_SUPPRESS_BROWSER_REFRESH dotnet watch run 尝试在检测到文件更改时刷新浏览器。 如果设置为“1”或“true”,则会取消此行为。 如果 DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER 已被设置,也会抑制此行为。

浏览器刷新

dotnet watch 将脚本注入应用,以便在内容更改时刷新浏览器。 在某些情况下,例如应用启用响应压缩时, dotnet watch可能无法注入 脚本。 对于开发中的此类情况,请手动将脚本注入应用。 例如,若要将 Web 应用配置为手动注入脚本,请更新布局文件以包括 _framework/aspnet-browser-refresh.js

@* _Layout.cshtml *@
<environment names="Development">
    <script src="/_framework/aspnetcore-browser-refresh.js"></script>
</environment>

非 ASCII 字符

Visual Studio 17.2 或更高版本包括 .NET SDK 6.0.300 或更高版本。 使用 .NET SDK 和 6.0.300 以后,在热重载会话期间向 dotnet-watch 控制台发出非 ASCII 字符。 在某些控制台主机上(如 Windows conhost),这些字符可能会被显示为乱码。 若要避免出现乱码字符,请考虑以下方法之一: