Entwickeln von ASP.NET Core-Apps mit einem Dateiwatcher

Von Rick Anderson und Victor Hurdugaci

dotnet watch ist ein Tool, das einen .NET CLI-Befehl ausführt, wenn sich Quelldateien ändern. Eine Dateiänderung kann beispielsweise eine Kompilierung, Testausführung oder Bereitstellung auslösen.

In diesem Tutorial wird eine vorhandene Web-API mit zwei Endpunkten verwendet: der eine gibt eine Summe zurück, der andere ein Produkt. Die Produktmethode enthält einen Fehler, der in diesem Tutorial behoben wird.

Laden Sie die Beispiel-App herunter. Sie enthält zwei Projekte: WebApp (eine ASP.NET Core-Web-API) und WebAppTests (Komponententest für die Web-API).

Navigieren Sie in einer Befehlsshell zum Ordner WebApp. Führen Sie den folgenden Befehl aus:

dotnet run

Hinweis

Sie können dotnet run --project <PROJECT> verwenden, um ein auszuführendes Projekt anzugeben. Wenn Sie beispielsweise im Stammverzeichnis der Beispiel-App dotnet run --project WebApp ausführen, wird auch das Projekt WebApp ausgeführt.

Die Konsolenausgabe zeigt Meldungen ähnlich der folgenden (die angibt, dass die App ausgeführt wird und auf Anforderungen wartet):

$ 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.

Navigieren Sie in einem Webbrowser zu http://localhost:<port number>/api/math/sum?a=4&b=5. Es sollten die Ergebnisse von 9 angezeigt werden.

Navigieren Sie zur Produkt-API (http://localhost:<port number>/api/math/product?a=4&b=5). Es wird nicht wie erwartet 20 sondern 9 zurückgegeben. Dieses Problem wird später im Tutorial behoben.

Hinzufügen von dotnet watch zu einem Projekt

Das Dateiwatcher-Tool dotnet watch ist im Lieferumfang von .NET Core SDK-Version 2.1.300 enthalten. Wenn Sie eine frühere Version von .NET Core SDK verwenden, sind die folgenden Schritte erforderlich.

  1. Fügen Sie der Datei .csproj einen Verweis auf das Paket Microsoft.DotNet.Watcher.Tools hinzu:

    <ItemGroup>
        <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
    </ItemGroup>
    
  2. Installieren Sie das Microsoft.DotNet.Watcher.Tools-Paket, indem Sie den folgenden Befehl ausführen:

    dotnet restore
    

Ausführen von .NET CLI-Befehlen mit dotnet watch

Jeder .NET CLI-Befehl kann mit dotnet watch ausgeführt werden. Zum Beispiel:

Befehl Befehl mit watch
dotnet run dotnet watch run
dotnet run -f netcoreapp3.1 dotnet watch run -f netcoreapp3.1
dotnet run -f netcoreapp3.1 -- --arg1 dotnet watch run -f netcoreapp3.1 -- --arg1
dotnet test dotnet watch test

Führen Sie dotnet watch run im Ordner WebApp aus. Die Konsolenausgabe gibt an, dass watch gestartet wurde.

Wenn dotnet watch run in einer Web-App ausgeführt wird, wird ein Browser aufgerufen, der nach der Bereitstellung zur URL der App navigiert. Dies geschieht bei dotnet watch, indem die Konsolenausgabe der App gelesen und auf die von WebHost angezeigte Bereitmeldung gewartet wird.

dotnet watch aktualisiert den Browser, wenn an den überwachten Dateien Änderungen erkannt werden. Hierzu wird mit dem Watch-Befehl eine Middleware in die App eingefügt, mit der durch die App erstellte HTML-Antworten geändert werden. Die Middleware fügt der Seite einen JavaScript-Block hinzu, mit dessen Hilfe dotnet watch den Browser anweist, eine Aktualisierung durchzuführen. Derzeit führen Änderungen an überwachten Dateien wie etwa an statischen Inhalten wie .html und .css-Dateien dazu, dass die App neu erstellt wird.

dotnet watch:

  • Überwacht nur Dateien, die sich standardmäßig auf Builds auswirken.
  • Alle (per Konfiguration) zusätzlich überwachten Dateien führen weiterhin dazu, dass ein Build erstellt wird.

Weitere Informationen zur Konfiguration finden Sie unter Konfiguration von dotnet-watch in diesem Dokument.

Hinweis

Sie können dotnet watch --project <PROJECT> verwenden, um ein zu überwachendes Projekt anzugeben. Wenn Sie beispielsweise im Stammverzeichnis der Beispiel-App dotnet watch --project WebApp run ausführen, wird auch das Projekt WebApp ausgeführt und überwacht.

Vornehmen von Änderungen mit dotnet watch

Stellen Sie sicher, dass dotnet watch ausgeführt wird.

Korrigieren Sie den Fehler in der Product-Methode von MathController.cs so, dass das Produkt und nicht die Summe zurückgegeben wird:

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

Speichern Sie die Datei. Die Konsolenausgabe zeigt an, dass dotnet watch eine Dateiänderung erkannt und die App neu gestartet hat.

Vergewissern Sie sich, dass http://localhost:<port number>/api/math/product?a=4&b=5 das richtige Ergebnis zurückgibt.

Ausführen von Tests mit dotnet watch

  1. Ändern Sie die Product-Methode von MathController.cs so, dass wieder die Summe zurückgegeben wird. Speichern Sie die Datei.

  2. Navigieren Sie in einer Befehlsshell zum Ordner WebAppTests.

  3. Führen Sie dotnet restore aus.

  4. Führen Sie aus dotnet watch test. In der Ausgabe wird angezeigt, dass ein Test fehlgeschlagen ist und der Watcher auf Dateiänderungen wartet:

    Total tests: 2. Passed: 1. Failed: 1. Skipped: 0.
    Test Run Failed.
    
  5. Ändern Sie den Code der Product-Methode so, dass das Produkt zurückgegeben wird. Speichern Sie die Datei.

dotnet watch erkennt die Dateiänderung und führt die Tests erneut aus. Die Konsolenausgabe zeigt, dass die Tests bestanden wurden.

Anpassen der Liste mit den zu überwachenden Dateien

Standardmäßig überwacht dotnet-watch alle Dateien mit den folgenden Globmustern:

  • **/*.cs
  • *.csproj
  • **/*.resx
  • Inhaltsdateien: wwwroot/**, **/*.config, **/*.json

Durch Bearbeiten der .csproj-Datei können der Watchlist weitere Elemente hinzugefügt werden. Dabei können die Elemente einzeln oder mithilfe von Globmustern angegeben werden.

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

Abwählen von zu überwachenden Dateien

Sie können dotnet-watch so konfigurieren, dass die Standardeinstellungen ignoriert werden. Wenn Sie bestimmte Dateien ignorieren möchten, fügen Sie der Definition eines Elements in der Datei .csproj das Watch="false"-Attribut hinzu:

<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>

Benutzerdefinierte Überwachungsprojekte

dotnet-watch ist nicht auf C#-Projekte beschränkt. Sie können für unterschiedliche Szenarios benutzerdefinierte Überwachungsprojekte erstellen. Betrachten Sie das folgende Projektlayout:

  • test/
    • UnitTests/UnitTests.csproj
    • IntegrationTests/IntegrationTests.csproj

Wenn beide Projekte überwacht werden sollen, erstellen Sie eine benutzerdefinierte Projektdatei, die so konfiguriert ist, dass beide Projekte überwacht werden:

<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>

Wechseln Sie zum Starten der Dateiüberwachung in beiden Projekten zum test-Ordner. Führen Sie den folgenden Befehl aus:

dotnet watch msbuild /t:Test

VSTest wird ausgeführt, wenn in einer beliebigen Datei in einem der Testprojekte Änderungen vorgenommen werden.

Konfiguration von dotnet-watch

Einige Konfigurationsoptionen können über Umgebungsvariablen an dotnet watch übergeben werden. Folgende Variablen sind verfügbar:

Einstellung BESCHREIBUNG
DOTNET_USE_POLLING_FILE_WATCHER Wenn diese Einstellung auf „1“ oder „true“ festgelegt ist, verwendet dotnet watch anstelle von FileSystemWatcher von CoreFx einen Polling-Dateiwatcher. Wird beim Überwachen von Dateien in Netzwerkfreigaben oder in auf Docker bereitgestellten Volumes verwendet.
DOTNET_WATCH_SUPPRESS_MSBUILD_INCREMENTALISM Das Build wird von dotnet watch standardmäßig optimiert. Dies geschieht dadurch, dass bestimmte Vorgänge wie das Ausführen einer Wiederherstellung oder die erneute Auswertung der überwachten Dateien bei jeder Dateiänderung vermieden werden. Wenn diese Einstellung auf „1“ oder TRUE festgelegt ist, werden diese Optimierungen deaktiviert.
DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER dotnet watch run versucht, Browser für Web-Apps zu starten, wobei launchBrowser in launchSettings.json konfiguriert ist. Wenn diese Einstellung auf „1“ oder „true“ festgelegt ist, wird dieses Verhalten unterdrückt.
DOTNET_WATCH_SUPPRESS_BROWSER_REFRESH dotnet watch run versucht, Browser zu aktualisieren, wenn Dateiänderungen erkannt werden. Wenn diese Einstellung auf „1“ oder „true“ festgelegt ist, wird dieses Verhalten unterdrückt. Dieses Verhalten wird auch unterdrückt, wenn DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER festgelegt ist.

Browseraktualisierung

dotnet watch fügt ein Skript in die App ein, das es ihr erlaubt, den Browser zu aktualisieren, wenn sich der Inhalt ändert. In einigen Szenarien, z. B. wenn die App die Antwortkomprimierung aktiviert, kann dotnet watch das Skript möglicherweise nicht einfügen. In solchen Fällen, die sich in der Entwicklung befinden, müssen Sie das Skript manuell in die App einfügen. Um beispielsweise die Web-App so zu konfigurieren, dass das Skript manuell eingefügt wird, aktualisieren Sie die Layoutdatei so, dass sie _framework/aspnet-browser-refresh.js enthält:

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

Nicht-ASCII-Zeichen

Visual Studio ab Version 17.2 enthält das .NET SDK 6.0.300 und höher. Mit dem .NET SDK ab 6.0.300 gibt dotnet-watch während einer Hot-Reload-Sitzung Nicht-ASCII-Zeichen an die Konsole aus. Auf bestimmten Konsolenhosts, wie z. B. Windows conhost, können diese Zeichen unlesbar angezeigt werden. Um unlesbare Zeichen zu vermeiden, sollten Sie einen der folgenden Ansätze wählen:

  • Konfigurieren Sie die Umgebungsvariable DOTNET_WATCH_SUPPRESS_EMOJIS=1 so, dass die Ausgabe dieser Werte unterdrückt wird.
  • Wechseln Sie zu einem anderen Terminal, z. B https://github.com/microsoft/terminal, das das Rendern von Nicht-ASCII-Zeichen unterstützt.