Freigeben über


Migrieren von ASP.NET Core in .NET 5 zu .NET 6

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

Voraussetzungen

Aktualisieren der .NET SDK-Version in global.json

Wenn Sie sich auf eine global.json Datei verlassen, die auf eine bestimmte .NET SDK-Version ausgerichtet ist, aktualisieren Sie die version Eigenschaft auf die .NET 6 SDK-Version, die installiert ist. Beispiel:

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

Aktualisieren des Zielframeworks

Aktualisieren Sie das 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. 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 .NET 6-Minimalhostingmodell für ASP.NET Core-Apps erfordert nur eine Datei und einige Codezeilen. Apps, die zu .NET 6 migrieren, müssen das neue minimale Hostingmodell nicht verwenden. Weitere Informationen finden Sie unter Apps, die zu .NET 6 migriert werden, müssen das neue minimale Hostingmodell im folgenden Abschnitt nicht verwenden.

Der folgende Code aus der ASP.NET Core leere 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 ist nur eine Datei mit vier Codezeilen erforderlich.
  • 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.
  • Verwendet globale using Direktiven, um die Anzahl der erforderlichen using Anweisungszeilen zu eliminieren oder zu minimieren.

Der folgende Code zeigt die Startup.cs- und Program.cs-Dateien aus einer .NET 5-Webanwendungsvorlage (Razor-Seiten) mit entfernten ungenutzten 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 in .NET 6 wird der vorherige 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();

Das vorhergehende Beispiel von ASP.NET Core in .NET 6 zeigt, wie:

Ausführliche Beispiele für die Migration von ASP.NET Core in .NET 5-Code Startup zu .NET 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; }
  • Standardwerte auf Protokollebene wurden geändert in appsettings.json und appsettings.Development.json:
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"

Aus dem früheren ASP.NET Core-Templatecode wurde "Microsoft": "Warning" zu "Microsoft.AspNetCore": "Warning" geändert. Diese Änderung führt dazu, dass alle Informationsmeldungen aus dem Microsoft Namespace außerMicrosoft.AspNetCore protokolliert werden. 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 .NET-Compiler-Nullzustandsanalyse finden Sie im Abschnitt Nullable Reference Types (NRTs) und .NET-Compiler-Nullzustandsanalyse.

Apps, die zu 6.0 oder höher migrieren oder verwenden, müssen das neue minimale Hostingmodell nicht verwenden.

Die Verwendung von Startup und dem generischen Host , der in den Vorlagen von ASP.NET Core 3.1 und 5.0 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 Startup mit dem minimalen Hostingmodell hat die folgenden Vorteile:

  • Zum Aufrufen der Startup-Klasse wird keine versteckte Reflexion verwendet.
  • Asynchroner Code kann geschrieben werden, da der Entwickler den Aufruf von Startup steuert.
  • Code kann geschrieben werden, der ConfigureServices und Configure verschachtelt.

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

Berücksichtigen Sie den folgenden Code, der von der Vorlage ASP.NET Core 3.1 oder 5.0 Razor Pages 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 vorherigen Code wird der if (env.IsDevelopment()) Block entfernt, da im Entwicklungsmodus die Middleware für Entwickler-Ausnahmeseiten standardmäßig aktiviert ist. Weitere Informationen finden Sie unter Unterschiede zwischen den ASP.NET Core in .NET 5- und .NET 6-Hostingmodellen im nächsten Abschnitt.

Fügen Sie bei Verwendung eines benutzerdefinierten Abhängigkeitsinjektionscontainers (DI) 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 Endpunktrouting-Middleware die gesamte Middlewarepipeline, daher ist es nicht erforderlich, explizite Aufrufe an UseRouting oder UseEndpoints um Routen zu registrieren. UseRouting kann weiterhin verwendet werden, um anzugeben, wo der Routenabgleich erfolgt, aber UseRouting muss nicht explizit aufgerufen werden, wenn Routen zu Beginn der Middleware-Pipeline abgeglichen werden sollen.

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

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 der Verwendung Startup mit dem neuen minimalen Hostingmodell den folgenden Unterschied:

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

Unterschiede zwischen den ASP.NET Core in .NET 5- und .NET 6-Hostingmodellen

  • Im Entwicklungsmodus ist die Entwickler-Fehlerseite-Middleware 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 in diesem Dokument.
  • Die Middleware für das Endpunktrouting umschließt die gesamte Middleware-Pipeline, deshalb müssen keine expliziten Aufrufe an UseRouting oder UseEndpoints erfolgen, um Routen zu registrieren. UseRouting kann weiterhin verwendet werden, um anzugeben, wo der Routenabgleich erfolgt, aber UseRouting muss nicht explizit aufgerufen werden, wenn Routen zu Beginn der Middleware-Pipeline abgeglichen werden 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 sind 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, ist es erforderlich, mit IServiceScope aufzurufen, um einen neuen Bereich zu instanziieren. Weitere Informationen finden Sie unter Eine Anleitung zur Lösung eines Dienstes beim Start der App.
  • Es ist nicht möglich, Hosteinstellungen wie den App-Namen, die Umgebung oder den Inhaltsstamm nach der Erstellung zu ändern. Ausführliche Anweisungen zum Ändern der Hosteinstellungen finden Sie unter Anpassen 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 von WebApplicationBuilder.Host oder WebApplicationBuilder.WebHostaus 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 von WebApplicationBuilder (WebApplicationBuilder.Host) verzögert die Ausführung der ConfigureServices, ConfigureAppConfiguration oder ConfigureHostConfiguration-Methoden nicht. Dadurch, dass die Ausführung nicht verzögert wird, kann Code mit WebApplicationBuilder Änderungen an IServiceCollection und IConfiguration überwachen. Das folgende Beispiel fügt Service1 nur als IService hinzu.

    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. Dies bedeutet, dass Service1 zu IServiceCollection hinzugefügt wird, bevor Service2, und führt dazu, dass Service1 für IService aufgelöst wird.

Erstellen von Bibliotheken für ASP.NET Core in .NET 6

Das vorhandene .NET-Ökosystem hat die Erweiterbarkeit um IServiceCollection, IHostBuilder und IWebHostBuilder aufgebaut. Diese Eigenschaften sind auf WebApplicationBuilder als Services, Host und WebHost verfügbar.

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

Wir erwarten, dass Bibliotheksautoren weiterhin IHostBuilder, IWebHostBuilder, IApplicationBuilder und IEndpointRouteBuilder beim Erstellen von ASP.NET Core-spezifischen Komponenten anstreben. Dadurch wird sichergestellt, dass Ihre Middleware, der Routinghandler oder andere Erweiterbarkeitspunkte weiterhin in verschiedenen Hostingmodellen funktionieren.

Häufig gestellte Fragen (FAQ)

  • Ist das neue minimale Hostingmodell weniger fä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 unbegrenzt unterstützt wird. Der generische Host unterstützt das neue Hostingmodell und ist weiterhin die primäre Methode zum Hosten von Worker-basierten Anwendungen.

  • Muss ich zum neuen Hostingmodell migrieren?

    Nein. Das neue Hostingmodell ist die bevorzugte Methode, um neue Apps mit .NET 6 oder höher zu hosten, aber Sie sind nicht gezwungen, das Projektlayout in vorhandenen Apps zu ändern. Dies bedeutet, dass Apps ein Upgrade von .NET 5 auf .NET 6 durchführen können, indem sie das Zielframework in der Projektdatei von net5.0 zu 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 nutzen zu können, die nur für das neue Hostingmodell verfügbar sind.

  • Muss ich Anweisungen der obersten Ebene verwenden?

    Nein. Die neuen Projektvorlagen verwenden alle Anweisungen auf oberster Ebene, aber die neuen Hosting-APIs können in jeder .NET 6-App verwendet werden, um einen Webserver oder eine Web-App zu hosten.

  • Wo füge ich den Zustand ein, der als Felder in meiner Program Oder Startup Klasse gespeichert wurde?

    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 von DI:

    • Speichern Sie den Status in einer anderen Klasse. Beim Speichern in einer Klasse wird ein statischer Zustand vorausgesetzt, auf den von überall in der App aus zugegriffen werden kann.

    • Verwenden Sie die Klasse Program, die von Anweisungen auf oberster Ebene generiert wird, um den Zustand zu speichern. Die Verwendung 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 zum Einfügen von Abhängigkeiten verwendet habe?

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

  • Funktionieren WebApplicationFactory und TestServer noch?

    Ja. WebApplicationFactory<TEntryPoint> ist die Möglichkeit, das neue Hostingmodell zu testen. Ein Beispiel finden Sie unter "Testen mitWebApplicationFactory" oder TestServer".

Blazor

Nachdem Sie den Anweisungen weiter oben in diesem Artikel folgen, um eine App auf .NET 6 zu aktualisieren, übernehmen Sie bestimmte Features, indem Sie den Links unter "Neuigkeiten" in ASP.NET Core in .NET 6 folgen.

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

  • Erstellen Sie ein neues 6.0-Projekt Blazor aus einer der Blazor Projektvorlagen. Weitere Informationen finden Sie unter Tooling for ASP.NET Core Blazor.
  • Verschieben Sie die Komponenten und den Code der App in die 6.0-App und nehmen Sie die notwendigen Änderungen vor, um die neuen .NET 6-Features zu integrieren.

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

Siehe Migrieren von React-Anwendungen aus Spa-Erweiterungen in diesem GitHub-Problem

Aktualisieren von Docker-Images

Für Apps, die Docker verwenden, aktualisieren Sie Ihre DockerfileFROM-Anweisungen und Skripte. Verwenden Sie ein Basisimage, das den ASP.NET Core in .NET 6 Runtime enthält. Beachten Sie den folgenden docker pull Befehlsunterschied zwischen ASP.NET Core in .NET 5 und .NET 6:

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

Siehe GitHub Issue Breaking Change: Standard-Konsolenprotokollierformat auf JSON festgelegt.

Änderungen am ASP.NET Core Razor SDK

Der Razor-Compiler nutzt nun die neue Quellgeneratoren-Funktion, um kompilierte C#-Dateien aus den Razor-Ansichten und -Seiten in einem Projekt zu generieren. In früheren Versionen:

  • Die Kompilierung basierte auf den Zielen RazorGenerate und RazorCompile, um den generierten Code zu erzeugen. Diese Ziele sind nicht mehr gültig. In .NET 6 werden sowohl die Codegenerierung als auch die Kompilierung 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 generiert, AppName.Views.dlldie 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, die eine Typ-Erkennung auf AppName.Views.dll durchführen, können keine Typ-Erkennung auf AppName.dll durchführen. Im Folgenden wird die API-Änderung gezeigt:
- 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 gelten nicht mehr für das einstufige Kompilierungsmodell.
    • RazorTargetAssemblyAttribute
    • RazorTargetName
    • EnableDefaultRazorTargetAssemblyInfoAttributes
    • UseRazorBuildServer
    • GenerateRazorTargetAssemblyInfo
    • GenerateMvcApplicationPartsAssemblyAttributes

Weitere Informationen finden Sie unter Razor Compiler erzeugt keine Views-Assembly mehr.

Project-Vorlagen verwenden Duende Identity Server

Project-Vorlagen verwenden jetzt Duende Identity Server.

Von Bedeutung

Duende Identity Server ist ein Open Source-Produkt mit einem gegenseitigen Lizenzvertrag. Wenn Sie beabsichtigen, Duende Server in der Produktion zu verwenden, müssen Sie möglicherweise eine kommerzielle Lizenz von Identity Software erwerben und eine Lizenzgebühr bezahlen. Weitere Informationen finden Sie unter Duende Software: Licenses.

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

Fügen Sie zu jedem DbSet<Key> eine Keys Eigenschaft namens IdentityDbContext hinzu, um eine neue Anforderung aus der aktualisierten Version von IPersistedGrantDbContext zu erfüllen. Die Schlüssel sind im Rahmen des Vertrags mit den Filialen von Duende Identity Server erforderlich.

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

Hinweis

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

Codebeispiele, die zu ASP.NET Core in .NET 6 migriert wurden

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 nullable Verweistypen (NRTs) verwenden, und der .NET-Compiler führt eine statische Nullzustandsanalyse durch. Diese Features wurden mit C# 8 veröffentlicht und sind standardmäßig für Apps aktiviert, die mit ASP.NET Core in .NET 6 (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 Nullstatusüberprüfung in Produktionsprojekten zu deaktivieren.

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

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 migrieren, haben nicht denselben App-Namen, da sie nicht normalisiert sind. Weitere Informationen finden Sie unter SetApplicationName

Weitere Ressourcen