Migrieren von ASP.NET Core 1.x zu 2.0

Von Scott Addie

In diesem Artikel aktualisieren wir exemplarisch ein vorhandenes ASP.NET Core 1.x-Projekt auf ASP.NET Core 2.0. Durch Migrieren der Anwendung zu ASP.NET Core 2.0 kommen Sie in den Genuss vieler neuer Funktionen und Leistungsverbesserungen.

Vorhandene ASP.NET Core 1.x-Anwendungen basieren auf versionsspezifischen Projektvorlagen. Doch das ASP.NET Core-Framework entwickelt sich weiter. Gleiches gilt für die darin enthaltenen Projektvorlagen und den Startercode. Zusätzlich zum Aktualisieren des ASP.NET Core-Frameworks müssen Sie den Code für Ihre Anwendung aktualisieren.

Voraussetzungen

Weitere Informationen finden Sie unter Erste Schritte mit ASP.NET Core.

Aktualisieren des Zielframeworkmonikers (Target Framework Moniker, TFM)

Auf .NET Core ausgelegte Projekte müssen den TFM einer Version größer gleich .NET Core 2.0 verwenden. Suchen Sie den Knoten <TargetFramework> in der CSPROJ-Datei, und ersetzen Sie dessen inneren Text durch netcoreapp2.0:

<TargetFramework>netcoreapp2.0</TargetFramework>

Auf .NET Framework ausgelegte Projekte müssen den TFM einer Version größer gleich .NET Framework 4.6.1 verwenden. Suchen Sie den Knoten <TargetFramework> in der CSPROJ-Datei, und ersetzen Sie dessen inneren Text durch net461:

<TargetFramework>net461</TargetFramework>

Hinweis

.NET Core 2.0 bietet eine viel größere Oberfläche als .NET Core 1.x. Wenn Sie mit .NET Framework entwickeln, nur weil APIs in .NET Core 1.x fehlen, wird das Entwickeln mit .NET Core 2.0 wahrscheinlich funktionieren.

Wenn die Projektdatei <RuntimeFrameworkVersion>1.{sub-version}</RuntimeFrameworkVersion> enthält, lesen Sie die Informationen zu diesem GitHub-Problem.

Aktualisieren der .NET Core SDK-Version in „global.json“

Wenn Ihre Projektmappe von einer Datei global.json abhängig ist, um eine bestimmte .NET Core SDK-Version als Ziel anzugeben, aktualisieren Sie deren version-Eigenschaft so, dass die auf Ihrem Computer installierte Version 2.0 verwendet wird:

{
  "sdk": {
    "version": "2.0.0"
  }
}

Aktualisieren von Paketverweisen

In der CSPROJ-Datei in einem Projekt der Version 1.x sind alle NuGet-Pakete aufgeführt, die vom Projekt verwendet werden.

In einem ASP.NET Core 2.0-Projekt für .NET Core 2.0 ersetzt ein einzelner Verweis des Typs metapackage in der CSPROJ-Datei die Paketsammlung:

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
</ItemGroup>

Alle Funktionen von ASP.NET Core 2.0 und Entity Framework Core 2.0 sind in „metapackage“ enthalten.

ASP.NET Core 2.0-Projekte für .NET Framework müssen weiterhin auf einzelne NuGet-Pakete verweisen. Aktualisieren Sie das Version-Attribut aller Knoten des Typs <PackageReference /> auf 2.0.0.

Hier ist z.B. die Liste der <PackageReference />-Knoten in einem typischen ASP.NET Core 2.0-Projekt für .NET Framework:

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
  <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.0.0" />
  <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="2.0.0" />
  <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.0.0" />
  <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
  <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.0.0" PrivateAssets="All" />
  <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
  <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" PrivateAssets="All" />
  <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
  <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" />
  <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" />
  <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" />
</ItemGroup>

Aktualisieren von .NET Core CLI-Tools

Aktualisieren Sie in der CSPROJ-Datei das Version-Attribut jedes <DotNetCliToolReference />-Knotens auf 2.0.0.

Hier ist z.B. die Liste der CLI-Tools in einem typischen ASP.NET Core 2.0-Projekt für .NET Core 2.0:

<ItemGroup>
  <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
  <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />
  <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>

Umbenennen der „TargetFallback“-Eigenschaft des Pakets

Die CSPROJ-Datei eines 1.x-Projekts hat einen Knoten des Typs PackageTargetFallback und eine Variable verwendet:

<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>

Benennen Sie den Knoten und die Variable in AssetTargetFallback um:

<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>

Aktualisieren der „Main“-Methode in „Program.cs“

In 1.x-Projekten sah die Main-Methode von Program.cs wie folgt aus:

using System.IO;
using Microsoft.AspNetCore.Hosting;

namespace AspNetCoreDotNetCore1App
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .UseApplicationInsights()
                .Build();

            host.Run();
        }
    }
}

In 2.0-Projekten wurde die Main-Methode von Program.cs vereinfacht:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace AspNetCoreDotNetCore2App
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

Das Übernehmen dieses neuen 2.0-Musters wird dringend empfohlen und ist für Produktfunktionen wie Entity Framework Core-Migrationen (EF) erforderlich. Bei Ausführung von Update-Database im Paket-Manager-Konsolenfenster oder von dotnet ef database update an der Befehlszeile (für in ASP.NET Core 2.0 konvertierte Projekte) wird der folgende Fehler generiert:

Unable to create an object of type '<Context>'. Add an implementation of 'IDesignTimeDbContextFactory<Context>' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

Hinzufügen von Konfigurationsanbietern

In 1.x-Projekten konnten Sie Konfigurationsanbieter einer App mit dem Startup-Konstruktor hinzufügen. Dazu mussten Sie eine Instanz von ConfigurationBuilder erstellen, die betreffenden Anbieter laden (Umgebungsvariablen, App-Einstellungen usw.) und einen Member von IConfigurationRoot initialisieren.

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

    if (env.IsDevelopment())
    {
        builder.AddUserSecrets<Startup>();
    }

    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

public IConfigurationRoot Configuration { get; }

Im vorherigen Beispiel wurde der Configuration-Member mit Konfigurationseinstellen aus appsettings.json geladen sowie aus jeder anderen appsettings.<EnvironmentName>.jso n-Datei, die mit der Eigenschaft IHostingEnvironment.EnvironmentName übereinstimmt. Diese Dateien befinden sich am gleichen Speicherort wie startup.cs.

In 2.0-Projekten wird der Bausteinkonfigurationsknoten, der 1.x-Projekten eigen ist, im Hintergrund ausgeführt. Umgebungsvariablen und App-Einstellungen werden beispielsweise beim Start geladen. Der entsprechende Code startup.cs wird zur IConfiguration-Initialisierung mit der eingefügten Instanz reduziert:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

Um die von WebHostBuilder.CreateDefaultBuilder hinzugefügten Standardanbieter zu entfernen, rufen Sie die Clear-Methode in der IConfigurationBuilder.Sources-Eigenschaft in ConfigureAppConfiguration auf. Um Anbieter wieder hinzuzufügen, verwenden Sie die ConfigureAppConfiguration-Methode in program.cs:

public static void Main(string[] args)
{
    BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureAppConfiguration((hostContext, config) =>
        {
            // delete all default configuration providers
            config.Sources.Clear();
            config.AddJsonFile("myconfig.json", optional: true);
        })
        .Build();

Die von der CreateDefaultBuilder-Methode verwendete Konfiguration im vorherigen Codeausschnitt können Sie sich hier ansehen.

Weitere Informationen finden Sie unter Konfiguration in ASP.NET Core.

Verschieben des Initialisierungscodes der Datenbank

In 1.x-Projekten, die EF Core 1.x verwenden, bewirkt ein Befehl wie dotnet ef migrations add Folgendes:

  1. Instanziiert eine Startup-Instanz
  2. Ruft die ConfigureServices-Methode auf, um alle Dienste mit Abhängigkeitsinjektion (einschließlich DbContext-Typen zu registrieren
  3. Führt die erforderlichen Aufgaben aus

In 2.0-Projekten, die EF Core 2.0 verwenden, wird Program.BuildWebHost aufgerufen, um die Anwendungsdienste abzurufen. Im Gegensatz zu 1.x hat dies den zusätzlichen Nebeneffekt, dass Startup.Configure aufgerufen wird. Wenn Ihre 1.x-App den Datenbankinitialisierungscode in der Configure-Methode aufgerufen hat, können unerwartete Probleme auftreten. Wenn die Datenbank beispielsweise noch nicht existiert, wird der Seedingcode vor der Befehlsausführung der EF Core-Migration ausgeführt. Dieses Problem führt dazu, dass ein dotnet ef migrations list-Befehl fehlschlägt, da die Datenbank noch nicht vorhanden ist.

Erwägen Sie den folgenden 1.x-Startcode der Initialisierung in der Configure-Methode von Startup.cs:

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

SeedData.Initialize(app.ApplicationServices);

Verschieben Sie in 2.0-Projekten den Aufruf SeedData.Initialize zur Main-Methode von Program.cs:

var host = BuildWebHost(args);

using (var scope = host.Services.CreateScope())
{
    var services = scope.ServiceProvider;

    try
    {
        // Requires using RazorPagesMovie.Models;
        SeedData.Initialize(services);
    }
    catch (Exception ex)
    {
        var logger = services.GetRequiredService<ILogger<Program>>();
        logger.LogError(ex, "An error occurred seeding the DB.");
    }
}

host.Run();

Ab 2.0 ist es keine gute Idee, etwas in BuildWebHost zu tun, außer den Webhost zu erstellen und zu konfigurieren. Alles, was in der Anwendung ausgeführt werden soll, sollte außerhalb von BuildWebHost — behandelt werden, in der Regel in der Main-Methode von Program.cs.

Überprüfen der Einstellungen für die Kompilierung der Razor-Ansicht

Eine schnellere Anwendungsstartzeit und kleinere veröffentlichte Pakete sind für Sie von höchster Wichtigkeit. Aus diesen Gründen ist Razor-Ansichtskompilierung in ASP.NET Core 2.0 standardmäßig aktiviert.

Das Festlegen der MvcRazorCompileOnPublish-Eigenschaft auf „true“ ist nicht mehr erforderlich. Außer wenn Sie die Ansichtskompilierung deaktivieren, kann die Eigenschaft aus der CSPROJ-Datei entfernt werden.

Bei Entwicklung für .NET Framework müssen Sie weiter explizit auf das NuGet-Paket Microsoft.AspNetCore.Mvc.Razor.ViewCompilation in Ihrer .csproj-Datei verweisen:

<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.0.0" PrivateAssets="All" />

Arbeiten mit den Startfeatures von Application Insights

Die mühelose Einrichtung der Instrumentierung der Anwendungsleistung ist wichtig. Hierfür können Sie nun mit den neuen Startfeatures von Application Insights in den Visual Studio 2017-Tools arbeiten.

Bei in Visual Studio 2017 erstellten ASP.NET Core 1.1-Projekten wurde Application Insights standardmäßig hinzugefügt. Wenn Sie das Application Insights SDK nicht direkt verwenden, gehen Sie außerhalb von Program.cs und Startup.cs folgendermaßen vor:

  1. Wenn .NET Core Ihr Ziel ist, entfernen Sie den folgenden <PackageReference />-Knoten aus der CSPROJ-Datei:

    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
    
  2. Wenn .NET Core Ihr Ziel ist, entfernen Sie den Aufruf der Erweiterungsmethode UseApplicationInsights aus Program.cs:

    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .Build();
    
        host.Run();
    }
    
  3. Entfernen Sie aus _Layout.cshtml den clientseitigen API-Aufruf von Application Insights. Dieser umfasst die beiden folgenden Codezeilen:

    @inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet
    @Html.Raw(JavaScriptSnippet.FullScript)
    

Sie können das Application Insights SDK weiterhin direkt verwenden. metapackage der Version 2.0 enthält die neueste Version von Application Insights, weshalb ein Fehler zum Downgrade eines Pakets angezeigt wird, wenn Sie auf eine ältere Version verweisen.

Übernehmen der Authentifizierung bzw. Verbesserungen an Identity

ASP.NET Core 2.0 verfügt über ein neues Authentifizierungsmodell und bietet eine Reihe wichtiger Änderungen an ASP.NET Core Identity. Wenn Sie Ihr Projekt mit aktivierter Option „Einzelne Benutzerkonten“ erstellt oder Authentifizierungs- oder Identitätsfunktionen manuell hinzugefügt haben, finden Sie unter Migrieren von Authentifizierungs- und Identitätseinstellungen nach ASP.NET Core 2.0 weitere Informationen.

Zusätzliche Ressourcen