Migrieren von ASP.NET Core 5.0 zu 6.0

In diesem Artikel wird erläutert, wie Sie ein vorhandenes ASP.NET Core 5.0-Projekt auf ASP.NET Core 6.0 aktualisieren. Anweisungen zum Migrieren von ASP.NET Core 3.1 zu ASP.NET Core 6.0 finden Sie unter Migrieren von ASP.NET Core 3.1 zu 6.0.

Voraussetzungen

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

Wenn Sie eine global.json-Datei für eine bestimmte .NET SDK-Version verwenden, aktualisieren Sie die version-Eigenschaft auf die installierte .NET 6.0 SDK-Version. Zum Beispiel:

{
  "sdk": {
-    "version": "5.0.100"
+    "version": "6.0.100"
  }
}

Aktualisieren des Zielframeworks

Aktualisieren Sie den Zielframeworkmoniker (Target Framework Moniker, TFM) der Projektdatei auf net6.0:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

</Project>

Aktualisieren von Paketverweisen

Aktualisieren Sie in der Projektdatei das Version-Attribut jedes Paketverweises vom Typ Microsoft.AspNetCore.* und Microsoft.Extensions.* auf 6.0.0 oder höher. Zum Beispiel:

<ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.3" />
-    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0" />
+    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="6.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
</ItemGroup>

Neues Hostingmodell

Das neue minimale .NET 6-Hostingmodell für ASP.NET Core-Apps erfordert nur eine Datei und einige Codezeilen. Apps, die zu 6.0 migriert werden, müssen das neue minimale Hostingmodell nicht verwenden. Weitere Informationen finden Sie im folgenden Abschnitt unter Apps, die zu 6.0 migriert werden, müssen das neue minimale Hostingmodell nicht verwenden.

Der folgende Code aus der leeren ASP.NET Core-Vorlage erstellt eine App mit dem neuen minimalen Hostingmodell:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Das minimale Hostingmodell:

  • Sie führt zu einer erheblich geringeren Anzahl der Dateien und Codezeilen, die zum Erstellen einer App erforderlich sind. Es wird nur eine einzelne Datei mit vier Codezeilen benötigt.
  • Sie vereinheitlicht Startup.cs und Program.cs in einer einzigen Program.cs-Datei.
  • Sie verwendet Anweisungen der obersten Ebene, um den für eine App erforderlichen Code zu minimieren.
  • Sie verwendet globale using-Anweisungen, um die Anzahl der erforderlichen Zeilen in einer using-Anweisung zu beseitigen oder zu minimieren.

Der folgende Code zeigt die Dateien Startup.cs und Program.cs aus einer ASP.NET Core 5-Web-App-Vorlage (Razor Pages) mit entfernten nicht verwendeten using-Anweisungen an:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// Unused usings removed.

namespace WebAppRPv5
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
    }
}
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
// Unused usings removed.

namespace WebAppRPv5
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

In ASP.NET Core 6 wird der vorangehende Code durch Folgendes ersetzt:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Im obigen Beispiel für ASP.NET Core 6 wird Folgendes gezeigt:

Ausführliche Beispiele für die Migration von ASP.NET Core 5 Startup-Code zu ASP.NET Core 6 mithilfe des minimalen Hostingmodells finden Sie weiter unten in diesem Dokument.

Es gibt einige Änderungen an den anderen Dateien, die für die Web-App-Vorlage generiert werden:

  • Aus Index.cshtml und Privacy.cshtml werden die nicht verwendeten using-Anweisungen entfernt.
  • RequestId in Error.cshtml wird als Nullable-Verweistyp (Nullable Reference Type, NRT) deklariert:
- public string RequestId { get; set; }
+ public string? RequestId { get; set; }
  • In appsettings.json und appsettings.Development.json wurden die Standardwerte auf Protokollebene geändert:
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"

Im vorherigen ASP.NET Core-Vorlagencode wurde "Microsoft": "Warning" in "Microsoft.AspNetCore": "Warning" geändert. Diese Änderung führt dazu, dass alle Informationsmeldungen aus dem Microsoft-Namespace protokolliert werden, mit Ausnahme von Microsoft.AspNetCore. Beispielsweise wird Microsoft.EntityFrameworkCore jetzt auf der Informationsebene protokolliert.

Weitere Informationen zum neuen Hostingmodell finden Sie im Abschnitt Häufig gestellte Fragen. Weitere Informationen zur Einführung von NRTs und der Analyse des .NET-Compilers mit NULL-Status finden Sie im Abschnitt Nullable-Verweistypen (NRTs) und statische Analyse des .NET-Compilers mit NULL-Status.

Apps, die zu 6.0 oder höher migriert werden oder eine entsprechende Version verwenden, müssen das neue minimale Hostingmodell nicht verwenden.

Die Verwendung von Startup und des generischen Hosts, der von den ASP.NET Core 3.1- und 5.0-Vorlagen verwendet wird, wird vollständig unterstützt.

Verwenden von Startup mit dem neuen minimalen Hostingmodell

ASP.NET Core 3.1- und 5.0-Apps können ihren Startup-Code mit dem neuen minimalen Hostingmodell verwenden. Die Verwendung von Startup mit dem minimalen Hostingmodell hat folgende Vorteile:

  • Zum Aufrufen der Startup-Klasse wird keine versteckte Reflexion verwendet.
  • Asynchroner Code kann geschrieben werden, da Entwickler*innen den Aufruf von Startup steuern.
  • Code kann geschrieben werden, der ConfigureServices und Configure verknüpft.

Eine geringfügige Einschränkung bei der Verwendung von Startup-Code mit dem neuen minimalen Hostingmodell besteht darin, dass der Dienst in Program.cs manuell aufgelöst werden muss, um eine Abhängigkeit in Configure einzufügen.

Betrachten Sie den folgenden Code, der von der Razor Pages-Vorlage für ASP.NET Core 3.1 oder 5.0 generiert wurde:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

Der vorangehende Code wurde zum neuen minimalen Hostingmodell migriert:

using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

var app = builder.Build();

startup.Configure(app, app.Environment);

app.Run();
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (!env.IsDevelopment())
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

Im obigen Code wird der if (env.IsDevelopment())-Block entfernt, da im Entwicklungsmodus die Middleware für die Entwicklerausnahmeseite standardmäßig aktiviert ist. Weitere Informationen finden Sie unter Unterschiede zwischen den Hostingmodellen von ASP.NET Core 5 und 6 im nächsten Abschnitt.

Fügen Sie bei Verwendung eines benutzerdefinierten Abhängigkeitsinjektionscontainers den folgenden hervorgehobenen Code hinzu:

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

// Using a custom DI container.
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(startup.ConfigureContainer);

var app = builder.Build();

startup.Configure(app, app.Environment);

app.Run();
using Autofac;
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    //  Using a custom DI container
    public void ConfigureContainer(ContainerBuilder builder)
    {
        // Configure custom container.
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (!env.IsDevelopment())
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

Bei Verwendung des minimalen Hostingmodells umschließt die Middleware für das Endpunktrouting die gesamte Middlewarepipeline, sodass keine expliziten Aufrufe von UseRouting oder UseEndpoints zum Registrieren von Routen erforderlich sind. UseRouting kann weiterhin verwendet werden, um anzugeben, wo der Routenabgleich erfolgt, UseRouting muss aber nicht explizit aufgerufen werden, wenn Routen am Anfang der Middlewarepipeline übereinstimmen sollen.

Im folgenden Code wurden die Aufrufe von UseRouting und UseEndpoints aus Startup entfernt. MapRazorPages wird in Program.cs aufgerufen:

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

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (!env.IsDevelopment())
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        //app.UseRouting();

        //app.UseEndpoints(endpoints =>
        //{
        //    endpoints.MapRazorPages();
        //});
    }
}
using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

var app = builder.Build();

startup.Configure(app, app.Environment);

app.MapRazorPages();

app.Run();

Beachten Sie bei Verwendung von Startup mit dem neuen minimalen Hostingmodell den folgenden Unterschied:

  • Program.cs steuert die Instanziierung und Lebensdauer der Startup-Klasse.
  • Alle zusätzlichen Dienste, die in die Configure-Methode eingefügt werden, müssen von der Program-Klasse manuell aufgelöst werden.

Unterschiede zwischen den Hostingmodellen von ASP.NET Core 5 und 6

  • Im Entwicklungsmodus ist die Middleware für die Entwicklerausnahmeseite standardmäßig aktiviert.
  • Der App-Name ist standardmäßig auf den Namen der Einstiegspunktassembly festgelegt: Assembly.GetEntryAssembly().GetName().FullName. Wenn Sie WebApplicationBuilder in einer Bibliothek verwenden, ändern Sie den App-Namen explizit in die Assembly der Bibliothek, damit die Anwendungspart-Ermittlung des MVC funktioniert. Ausführliche Anweisungen finden Sie unter Ändern des Inhaltsstamms, des App-Namens und der Umgebung.
  • Die Middleware für das Endpunktrouting umschließt die gesamte Middlewarepipeline, sodass keine expliziten Aufrufe von UseRouting oder UseEndpoints zum Registrieren von Routen erforderlich sind. UseRouting kann weiterhin verwendet werden, um anzugeben, wo der Routenabgleich erfolgt, UseRouting muss aber nicht explizit aufgerufen werden, wenn Routen am Anfang der Middlewarepipeline übereinstimmen sollen.
  • Die Pipeline wird vor allen IStartupFilter-Ausführungen erstellt, sodass Ausnahmen, die beim Erstellen der Pipeline verursacht werden, für die IStartupFilter-Aufrufkette nicht sichtbar sind.
  • Einige Tools, z. B. EF-Migrationen, verwenden Program.CreateHostBuilder, um auf den Dienstanbieter (IServiceProvider) der App zuzugreifen und benutzerdefinierte Logik im Kontext der App auszuführen. Diese Tools wurden aktualisiert, um eine neue Technik zum Ausführen von benutzerdefinierter Logik im Kontext der App zu verwenden. Entity Framework-Migrationen ist ein Beispiel für ein Tool, das Program.CreateHostBuilder auf diese Weise verwendet. Wir arbeiten daran, sicherzustellen, dass Tools aktualisiert werden, um das neue Modell zu verwenden.
  • Im Gegensatz zur Startup-Klasse konfiguriert der minimale Host beim Instanziieren des Dienstanbieters nicht automatisch einen DI-Bereich. Für Kontexte, in denen ein Bereich erforderlich ist, müssen Sie IServiceScope mit IServiceScopeFactory.CreateScope aufrufen, um einen neuen Bereich zu instanziieren. Weitere Informationen finden Sie unter Auflösen eines Diensts beim App-Start.
  • Nach der Erstellung von WebApplicationBuilder ist das Ändern von Hosteinstellungen wie App-Name, Umgebung oder Inhaltsstammnicht mehr möglich. Ausführliche Anweisungen zum Ändern von Hosteinstellungen finden Sie unter Anpassen von IHostBuilder oder IWebHostBuilder. Die folgenden hervorgehobenen APIs lösen eine Ausnahme aus:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

// WebHost

try
{
    builder.WebHost.UseContentRoot(Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseEnvironment(Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.ApplicationKey, "ApplicationName2");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.ContentRootKey, Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    builder.WebHost.UseSetting(WebHostDefaults.EnvironmentKey, Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

// Host
try
{
    builder.Host.UseEnvironment(Environments.Staging);
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

try
{
    // TODO: This does not throw
    builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();
  • Die Startup-Klasse kann nicht über WebApplicationBuilder.Host oder WebApplicationBuilder.WebHost verwendet werden. Der folgende hervorgehobene Code löst eine Ausnahme aus:

    var builder = WebApplication.CreateBuilder(args);
    
    try
    {
        builder.Host.ConfigureWebHostDefaults(webHostBuilder =>
        {
            webHostBuilder.UseStartup<Startup>();
        });
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        throw;    
    }
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
    var builder = WebApplication.CreateBuilder(args);
    
    try
    {
        builder.WebHost.UseStartup<Startup>();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        throw;    
    }
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
  • Die IHostBuilder-Implementierung für WebApplicationBuilder (WebApplicationBuilder.Host) verzögert die Ausführung der Methoden ConfigureServices, ConfigureAppConfiguration und ConfigureHostConfiguration nicht. Dadurch, dass die Ausführung nicht verzögert wird, kann Code mit WebApplicationBuilder Änderungen an IServiceCollection und IConfiguration überwachen. Im folgenden Beispiel wird nur Service1 als IService hinzugefügt:

    using Microsoft.Extensions.DependencyInjection.Extensions;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Host.ConfigureServices(services =>
    {
        services.TryAddSingleton<IService, Service1>();
    });
    
    builder.Services.TryAddSingleton<IService, Service2>();
    
    var app = builder.Build();
    
    // Displays Service1 only.
    Console.WriteLine(app.Services.GetRequiredService<IService>());
    
    app.Run();
    
    class Service1 : IService
    {
    }
    
    class Service2 : IService
    {
    }
    
    interface IService
    {
    }
    

Im vorangehenden Code wird der builder.Host.ConfigureServices-Rückruf inline aufgerufen, anstatt verzögert zu werden, bis builder.Build aufgerufen wird. Das bedeutet, dass Service1 zu IServiceCollection vor Service2 hinzugefügt wird, sodass Service1 für IService aufgelöst wird.

Erstellen von Bibliotheken für ASP.NET Core 6

Im vorhandenen .NET-Ökosystem wurde Erweiterbarkeit rund um IServiceCollection, IHostBuilder und IWebHostBuilder aufgebaut. Diese Eigenschaften sind für WebApplicationBuilder als Services, Host und WebHostverfügbar.

WebApplication implementiert sowohl Microsoft.AspNetCore.Builder.IApplicationBuilder als auch Microsoft.AspNetCore.Routing.IEndpointRouteBuilder.

Wir erwarten, dass Bibliotheksautor*innen beim Erstellen ASP.NET Core-spezifischer Komponenten weiterhin IHostBuilder, IWebHostBuilder, IApplicationBuilder und IEndpointRouteBuilder als Ziel verwenden. Dadurch wird sichergestellt, dass Ihre Middleware, Ihr Routenhandler oder andere Erweiterbarkeitspunkte weiterhin in verschiedenen Hostingmodellen funktioniert bzw. funktionieren.

Häufig gestellte Fragen (FAQ)

  • Ist das neue minimale Hostingmodell weniger leistungsfähig?

    Nein. Die Funktionen des neuen Hostingmodells decken 98 % der Szenarien ab, die von IHostBuilder und IWebHostBuilder unterstützt werden. Es gibt einige erweiterte Szenarien, die bestimmte Problemumgehungen für IHostBuilder erfordern, aber wir erwarten, dass diese äußerst selten sind.

  • Ist das generische Hostingmodell veraltet?

    Nein. Das generische Hostingmodell ist ein alternatives Modell, das zeitlich unbegrenzt unterstützt wird. Der generische Host untermauert das neue Hostingmodell und ist weiterhin die primäre Methode zum Hosten von workerbasierten Anwendungen.

  • Muss ich zum neuen Hostingmodell migrieren?

    Nein. Das neue Hostingmodell ist die bevorzugte Methode zum Hosten neuer Apps mit .NET 6 und höher, aber Sie sind nicht gezwungen, das Projektlayout in vorhandenen Apps zu ändern. Das bedeutet, dass für Apps ein Upgrade von .NET 5 auf .NET 6 durchgeführt werden kann, indem Sie das Zielframework in der Projektdatei von net5.0 in net6.0 ändern. Weitere Informationen finden Sie im Abschnitt Aktualisieren des Zielframeworks in diesem Artikel. Es wird jedoch empfohlen, Apps zum neuen Hostingmodell zu migrieren, um neue Features zu nutzen, die nur für das neue Hostingmodell verfügbar sind.

  • Muss ich Anweisungen der obersten Ebene verwenden?

    Nein. Die neuen Projektvorlagen verwenden alle Anweisungen der obersten Ebene, aber die neuen Hosting-APIs können in einer beliebigen .NET 6-App zum Hosten eines Webservers oder einer Web-App verwendet werden.

  • Wo platziere ich als Felder gespeicherten Zustand in meiner Program- oder Startup-Klasse?

    Es wird dringend empfohlen, die Abhängigkeitsinjektion (Dependency Injection, DI) für den Flowstatus in ASP.NET Core-Apps zu verwenden.

    Es gibt zwei Ansätze zum Speichern des Zustands außerhalb der DI:

    • Speichern Sie den Zustand in einer anderen Klasse. Beim Speichern in einer Klasse wird von einem statischen Zustand ausgegangen, auf den von überall in der App zugegriffen werden kann.

    • Verwenden Sie die von Anweisungen der obersten Ebene generierte Program-Klasse, um den Zustand zu speichern. Die Verwendung von Program zum Speichern des Zustands ist der semantische Ansatz:

      var builder = WebApplication.CreateBuilder(args);
      
      ConfigurationValue = builder.Configuration["SomeKey"] ?? "Hello";
      
      var app = builder.Build();
      
      app.MapGet("/", () => ConfigurationValue);
      
      app.Run();
      
      partial class Program
      {
          public static string? ConfigurationValue { get; private set; }
      }
      
  • Was geschieht, wenn ich einen benutzerdefinierten Container für die Abhängigkeitsinjektion verwendet habe?

    Benutzerdefinierte Abhängigkeitsinjektionscontainer werden unterstützt. Ein Beispiel finden Sie unter Benutzerdefinierte Abhängigkeitsinjektionscontainer.

  • Funktionieren WebApplicationFactory und TestServer noch?

    Ja. Mit WebApplicationFactory<TEntryPoint> können Sie das neue Hostingmodell testen. Ein Beispiel finden Sie unter Testen mit WebApplicationFactory oder TestServer.

Blazor

Nachdem Sie die weiter oben in diesem Artikel beschriebene Anleitung zum Aktualisieren einer App auf 6.0 befolgt haben, können Sie bestimmte Features einführen, indem Sie den Links unter Neuerungen in ASP.NET Core 6.0 folgen.

Um alle neuen 6.0-Features für Blazor-Apps einzuführen, empfehlen wir den folgenden Prozess:

  • Erstellen Sie ein neues Blazor-Projekt für 6.0 auf der Grundlage einer der Blazor-Projektvorlagen. Weitere Informationen finden Sie unter Tools für ASP.NET Core Blazor.
  • Migrieren Sie die Komponenten und den Code der App zur 6.0-App, und nehmen Sie Änderungen vor, um die neuen 6.0-Features einzuführen.

Migrieren von SPA-Projekten

Migrieren von Angular-Apps aus SPA-Erweiterungen

Weitere Informationen finden Sie in diesem GitHub-Issue.

Migrieren von React-Apps aus SPA-Erweiterungen

Weitere Informationen finden Sie unter Migrieren von React-Anwendungen aus SPA-Erweiterungen in diesem GitHub-Issue.

Aktualisieren von Docker-Images

Aktualisieren Sie für Apps, die Docker verwenden, Ihre Dockerfile-FROM-Anweisungen und Skripts. Verwenden Sie ein Basisimage, das die ASP.NET Core 6.0-Runtime enthält. Beachten Sie den folgenden Unterschied beim Befehl docker pull zwischen ASP.NET Core 5.0 und 6.0:

- docker pull mcr.microsoft.com/dotnet/aspnet:5.0
+ docker pull mcr.microsoft.com/dotnet/aspnet:6.0

Weitere Informationen finden Sie im GitHub-Issue Breaking Change: Standardformatierung der Konsolenprotokollierung auf JSON festgelegt.

Änderungen am ASP.NET Core Razor SDK

Der Razor-Compiler nutzt jetzt das neue Feature Quellcode-Generatoren, um kompilierte C#-Dateien auf der Grundlage der Razor-Ansichten und -Seiten in einem Projekt zu generieren. In vorherigen Versionen galt Folgendes:

  • Bei der Kompilierung wurden die Ziele RazorGenerate und RazorCompile verwendet, um den generierten Code zu erzeugen. Diese Ziele sind nicht mehr gültig. In .NET 6 werden Codegenerierung und Codekompilierung durch einen einzelnen Aufruf des Compilers unterstützt. RazorComponentGenerateDependsOn wird weiterhin unterstützt, um Abhängigkeiten anzugeben, die vor der Ausführung des Builds erforderlich sind.
  • Es wurde eine separate Razor-Assembly (AppName.Views.dll) generiert, die die kompilierten Ansichtstypen in einer Anwendung enthielt. Dieses Verhalten ist veraltet, und eine einzelne Assembly (AppName.dll) wird erstellt, die sowohl die App-Typen als auch die generierten Ansichten enthält.
  • Die App-Typen in AppName.Views.dll waren öffentlich. In .NET 6 befinden sich die App-Typen in AppName.dll, sind aber internal sealed. Apps mit Typermittlung für AppName.Views.dll können keine Typermittlung für AppName.dll durchführen. Hier sehen Sie die API-Änderung:
- public class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
+ internal sealed class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>

Nehmen Sie die folgenden Änderungen vor:

  • Die folgenden Eigenschaften sind beim einstufigen Kompilierungsmodell nicht mehr gültig:
    • RazorTargetAssemblyAttribute
    • RazorTargetName
    • EnableDefaultRazorTargetAssemblyInfoAttributes
    • UseRazorBuildServer
    • GenerateRazorTargetAssemblyInfo
    • GenerateMvcApplicationPartsAssemblyAttributes

Weitere Informationen finden Sie unter Razor compiler no longer produces a Views assembly.

Projektvorlagen verwenden Duende Identity Server

Projektvorlagen verwenden jetzt Duende Identity Server.

Wichtig

Duende Identity Server ist ein Open Source-Produkt mit einer gegenseitigen Lizenzvereinbarung. Wenn Sie planen, Duende Identity Server in der Produktion zu verwenden, müssen Sie möglicherweise eine kommerzielle Lizenz von Duende Software erwerben und eine Lizenzgebühr bezahlen. Weitere Informationen finden Sie bei Duende Software unter Licences.

Informationen zur Verwendung von Microsoft Azure Active Directory für ASP.NET Core Identity finden Sie unter Identity (GitHub-Repository „dotnet/aspnetcore“).

Fügen Sie jeder Instanz von IdentityDbContext eine DbSet<Key>-Eigenschaft namens Keys hinzu, um eine neue Anforderung aus der aktualisierten Version von IPersistedGrantDbContext zu erfüllen. Die Schlüssel werden im Rahmen des Vertrags mit den Speichern von Duende Identity Server benötigt.

public DbSet<Key> Keys { get; set; }

Hinweis

Vorhandene Migrationen müssen für Duende Identity Server neu erstellt werden.

Zu ASP.NET Core 6.0 migrierte Codebeispiele

Codebeispiele, die zum neuen minimalen Hostingmodell in 6.0 migriert wurden

Überprüfen von Breaking Changes

Weitere Informationen finden Sie in den folgenden Ressourcen:

Nullable-Verweistypen (NRTs) und statische Analyse des .NET-Compilers mit NULL-Status

ASP.NET Core-Projektvorlagen verwenden Nullable-Verweistypen (Nullable Reference Types, NRTs), und der .NET-Compiler führt statische Analysen mit NULL-Status durch. Diese Features wurden mit C# 8 veröffentlicht und sind standardmäßig für Apps aktiviert, die mit ASP.NET Core 6.0 (C# 10) oder höher generiert wurden.

Die Warnungen der statischen Analyse mit NULL-Status des .NET-Compilers können als Orientierungshilfe für die lokale Aktualisierung eines Dokumentationsbeispiels oder einer Beispiel-App dienen oder ignoriert werden. Die statische Analyse mit NULL-Status kann deaktiviert werden, indem in der Projektdatei der App Nullable auf disable festgelegt wird. Dies wird nur für Dokumentationsbeispiele und Beispiel-Apps empfohlen, wenn die Compilerwarnungen beim Lernen der Verwendung von .NET störend sind. Es wird nicht empfohlen, die Überprüfung des NULL-Status in Produktionsprojekten zu deaktivieren.

Weitere Informationen zu NRTs, zur MSBuild-Eigenschaft Nullable und zum Aktualisieren von Apps (einschließlich #pragma-Anleitungen) finden Sie in den folgenden Ressourcen in der C#-Dokumentation:

ASP.NET Core-Modul (ANCM)

Wenn das ASP.NET Core-Modul (ANCM) bei der Installation von Visual Studio keine ausgewählte Komponente war oder wenn eine frühere Version des ANCM auf dem System installiert wurde, laden Sie den neuesten Installer für das .NET Core Hosting-Paket (direkter Download) herunter, und führen Sie das Installationsprogramm aus. Weitere Informationen finden Sie unter Das .NET Core-Hostingbundle.

Änderung des Anwendungsnamens

In .NET 6 normalisiert WebApplicationBuilder den Inhaltsstammpfad so, dass er mit DirectorySeparatorChar endet. Die meisten Apps, die von HostBuilder oder WebHostBuilder migriert werden, haben nicht denselben App-Namen, da sie nicht normalisiert sind. Weitere Informationen finden Sie unter SetApplicationName.

Zusätzliche Ressourcen