Migrowanie z ASP.NET Core 2.2 do wersji 3.0

Autor: Scott Addie i Rick Anderson

W tym artykule wyjaśniono, jak zaktualizować istniejący projekt ASP.NET Core 2.2 w celu ASP.NET Core 3.0. Warto utworzyć nowy projekt ASP.NET Core 3.0 w celu:

  • Porównaj z kodem ASP.NET Core 2.2.
  • Skopiuj odpowiednie zmiany do projektu ASP.NET Core 3.0.

Wymagania wstępne

Aktualizowanie wersji zestawu .NET Core SDK w programie global.json

Jeśli rozwiązanie opiera się na global.json pliku przeznaczonym dla określonej wersji zestawu .NET Core SDK, zaktualizuj jego version właściwość do wersji 3.0 zainstalowanej na maszynie:

{
  "sdk": {
    "version": "3.0.100"
  }
}

Aktualizowanie pliku projektu

Aktualizowanie platformy docelowej

ASP.NET Core 3.0 i nowsze są uruchamiane tylko na platformie .NET Core. Ustaw nazwę Moniker platformy docelowej (TFM) na netcoreapp3.0:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

Usuwanie przestarzałych odwołań do pakietu

Duża liczba pakietów NuGet nie jest generowanych dla platformy ASP.NET Core 3.0. Takie odwołania do pakietu powinny zostać usunięte z pliku projektu. Rozważ następujący plik projektu dla aplikacji internetowej ASP.NET Core 2.2:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App"/>
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
  </ItemGroup>

</Project>

Zaktualizowany plik projektu dla ASP.NET Core 3.0:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

Zaktualizowany plik projektu ASP.NET Core 3.0:

  • W pliku <PropertyGroup>:

    • Aktualizacje serwera TFM donetcoreapp3.0
    • <AspNetCoreHostingModel> Usuwa element. Aby uzyskać więcej informacji, zobacz Model hostingu w procesie w tym dokumencie.
  • W pliku <ItemGroup>:

    • Microsoft.AspNetCore.App jest usuwana. Aby uzyskać więcej informacji, zobacz Dokumentacja platformy w tym dokumencie.
    • Microsoft.AspNetCore.Razor.Design program zostanie usunięty i na poniższej liście pakietów nie są już tworzone.

Aby wyświetlić pełną listę pakietów, które nie są już generowane, wybierz następującą listę rozwijaną:

Kliknij, aby rozwinąć listę pakietów, które nie są już tworzone
  • Microsoft.AspNetCore
  • Microsoft.AspNetCore.All
  • Microsoft.AspNetCore.App
  • Microsoft.AspNetCore.Antiforgery
  • Microsoft.AspNetCore.Authentication
  • Microsoft.AspNetCore.Authentication.Abstractions
  • Microsoft.AspNetCore.Authentication.CookieS
  • Microsoft.AspNetCore.Authentication.Core
  • Microsoft.AspNetCore.Authentication.OAuth
  • Microsoft.AspNetCore.Authorization.Policy
  • Microsoft.AspNetCore.CookieZasad
  • Microsoft.AspNetCore.Cors
  • Microsoft.AspNetCore.Diagnostics
  • Microsoft.AspNetCore.Diagnostics.HealthChecks
  • Microsoft.AspNetCore.HostFiltering
  • Microsoft.AspNetCore.Hosting
  • Microsoft.AspNetCore.Hosting.Abstractions
  • Microsoft.AspNetCore.Hosting.Server.Abstractions
  • Microsoft.AspNetCore.Http
  • Microsoft.AspNetCore.Http.Abstractions
  • Microsoft.AspNetCore.Http.Connections
  • Microsoft.AspNetCore.Http.Extensions
  • Microsoft.AspNetCore.HttpOverrides
  • Microsoft.AspNetCore.HttpsPolicy
  • Microsoft.AspNetCore.Identity
  • Microsoft.AspNetCore.Localization
  • Microsoft.AspNetCore.Localization.Routing
  • Microsoft.AspNetCore.Mvc
  • Microsoft.AspNetCore.Mvc.Abstractions
  • Microsoft.AspNetCore.Mvc.Analyzers
  • Microsoft.AspNetCore.Mvc.ApiExplorer
  • Microsoft.AspNetCore.Mvc.Api.Analyzers
  • Microsoft.AspNetCore.Mvc.Core
  • Microsoft.AspNetCore.Mvc.Cors
  • Microsoft.AspNetCore.Mvc.DataAnnotations
  • Microsoft.AspNetCore.Mvc.Formatters.Json
  • Microsoft.AspNetCore.Mvc.Formatters.Xml
  • Microsoft.AspNetCore.Mvc.Localization
  • Microsoft.AspNetCore.Mvc.Razor
  • Microsoft.AspNetCore.Mvc.Razor. ViewCompilation
  • Microsoft.AspNetCore.Mvc.RazorStron
  • Microsoft.AspNetCore.Mvc.TagHelpers
  • Microsoft.AspNetCore.Mvc.ViewFeatures
  • Microsoft.AspNetCore.Razor
  • Microsoft.AspNetCore.Razor. Środowiska wykonawczego
  • Microsoft.AspNetCore.Razor. Projektowania
  • Microsoft.AspNetCore.ResponseCaching
  • Microsoft.AspNetCore.ResponseCaching.Abstractions
  • Microsoft.AspNetCore.ResponseCompression
  • Microsoft.AspNetCore.Rewrite
  • Microsoft.AspNetCore.Routing
  • Microsoft.AspNetCore.Routing.Abstractions
  • Microsoft.AspNetCore.Server.HttpSys
  • Microsoft.AspNetCore.Server.IIS
  • Microsoft.AspNetCore.Server.IISIntegration
  • Microsoft.AspNetCore.Server.Kestrel
  • Microsoft.AspNetCore.Server.Kestrel. Core
  • Microsoft.AspNetCore.Server.Kestrel. Https
  • Microsoft.AspNetCore.Server.Kestrel. Transport.Abstractions
  • Microsoft.AspNetCore.Server.Kestrel. Transport.Sockets
  • Microsoft.AspNetCore.Session
  • Microsoft.AspNetCore.SignalR
  • Microsoft.AspNetCore.SignalR. Core
  • Microsoft.AspNetCore.StaticFiles
  • Microsoft.AspNetCore.WebSockets
  • Microsoft.AspNetCore.WebUtilities
  • Microsoft.Net.Http.Headers

Przeglądanie zmian powodujących niezgodność

Przeglądanie zmian powodujących niezgodność

Dokumentacja platformy

Funkcje ASP.NET Core, które były dostępne za pośrednictwem jednego z pakietów wymienionych powyżej, są dostępne w ramach struktury udostępnionej Microsoft.AspNetCore.App . Platforma udostępnionato zestaw zestawów (plików dll), które są zainstalowane na maszynie i zawierają składnik środowiska uruchomieniowego i pakiet docelowy. Aby uzyskać więcej informacji, zobacz Struktura udostępniona.

  • Projekty przeznaczone dla zestawu Microsoft.NET.Sdk.Web SDK niejawnie odwołują się do platformy Microsoft.AspNetCore.App .

    Dla tych projektów nie są wymagane żadne dodatkowe odwołania:

    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
        ...
    </Project>
    
  • Projekty przeznaczone dla elementu docelowego Microsoft.NET.Sdk lub Microsoft.NET.Sdk.Razor zestawu SDK powinny dodać jawny FrameworkReference element do Microsoft.AspNetCore.Appelementu :

    <Project Sdk="Microsoft.NET.Sdk.Razor">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
      </ItemGroup>
        ...
    </Project>
    

Kompilacje zależne od struktury przy użyciu platformy Docker

Kompilacje zależne od struktury aplikacji konsoli korzystających z pakietu zależnego od platformy udostępnionej ASP.NET Core mogą spowodować następujący błąd środowiska uruchomieniowego:

It was not possible to find any compatible framework version
The specified framework 'Microsoft.AspNetCore.App', version '3.0.0' was not found.
  - No frameworks were found.

Microsoft.AspNetCore.App to udostępniona struktura zawierająca środowisko uruchomieniowe ASP.NET Core i jest obecna tylko na obrazie platformy dotnet/core/aspnet Docker. Zestaw SDK 3.0 zmniejsza rozmiar kompilacji zależnych od platformy przy użyciu platformy ASP.NET Core, nie dołączając zduplikowanych kopii bibliotek dostępnych w strukturze udostępnionej. Jest to potencjalne oszczędności do 18 MB, ale wymaga, aby środowisko uruchomieniowe ASP.NET Core było obecne / zainstalowane w celu uruchomienia aplikacji.

Aby ustalić, czy aplikacja ma zależność (bezpośrednią lub pośrednią) na platformie udostępnionej ASP.NET Core, sprawdź runtimeconfig.json plik wygenerowany podczas kompilacji/publikowania aplikacji. JSPoniższy plik ON pokazuje zależność od platformy udostępnionej ASP.NET Core:

{
  "runtimeOptions": {
    "tfm": "netcoreapp3.0",
    "framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "3.0.0"
    },
    "configProperties": {
      "System.GC.Server": true
    }
  }
}

Jeśli aplikacja korzysta z platformy Docker, użyj obrazu podstawowego zawierającego ASP.NET Core 3.0. Na przykład docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0.

Dodawanie odwołań do pakietów dla usuniętych zestawów

ASP.NET Core 3.0 usuwa niektóre zestawy, które były wcześniej częścią Microsoft.AspNetCore.App odwołania do pakietu. Aby zwizualizować, które zestawy zostały usunięte, porównaj dwa foldery struktury udostępnionej. Na przykład porównanie wersji 2.2.7 i 3.0.0:

shared framework assemblies comparison

Aby kontynuować korzystanie z funkcji udostępnianych przez usunięte zestawy, należy odwołać się do wersji 3.0 odpowiednich pakietów:

Zmiany uruchamiania

Na poniższej ilustracji przedstawiono usunięte i zmienione wiersze w aplikacji internetowej ASP.NET Core 2.2 Razor Pages:

the deleted and changed lines in an ASP.NET Core 2.2 Razor Web app

Na powyższym obrazie usunięty kod jest wyświetlany na czerwono. Usunięty kod nie wyświetla cookie kodu opcji, który został usunięty przed porównaniem plików.

Na poniższej ilustracji przedstawiono dodane i zmienione wiersze w aplikacji internetowej ASP.NET Core 3.0 Razor Pages:

the added and changed lines in an ASP.NET Core 3.0 Razor Web app

Na powyższym obrazie dodany kod jest wyświetlany na zielono. Aby uzyskać informacje na temat następujących zmian:

  • services.AddMvcaby wyświetlić services.AddRazorPagesrejestrację usługi MVC w tym dokumencie.
  • CompatibilityVersion, zobacz Wersja zgodności dla ASP.NET Core MVC.
  • IHostingEnvironmentaby wyświetlić IWebHostEnvironmentto ogłoszenie w witrynie GitHub.
  • app.UseAuthorization dodano do szablonów, aby wyświetlić oprogramowanie pośredniczące autoryzacji zamówienia. Jeśli aplikacja nie używa autoryzacji, możesz bezpiecznie usunąć wywołanie metody app.UseAuthorization.
  • app.UseEndpoints, zobacz Razor Strony lub Migrowanie uruchamiania.Konfigurowanie w tym dokumencie.

Obsługa analizatora

Projekty przeznaczone Microsoft.NET.Sdk.Web dla niejawnie odwołujących się do analizatorów wcześniej dostarczanych w ramach pakietu Microsoft.AspNetCore.Mvc.Analyzers . Do ich włączenia nie są wymagane żadne dodatkowe odwołania.

Jeśli aplikacja korzysta z analizatorów interfejsu API dostarczonych wcześniej przy użyciu pakietu Microsoft.AspNetCore.Mvc.Api.Analyzers , zmodyfikuj plik projektu, aby odwołać się do analizatorów dostarczonych w ramach zestawu .NET Core Web SDK:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
    </PropertyGroup>

    ...
</Project>

Razor Biblioteka klas

Razor Projekty biblioteki klas, które udostępniają składniki interfejsu użytkownika dla wzorca MVC, muszą ustawić AddRazorSupportForMvc właściwość w pliku projektu:

<PropertyGroup>
  <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>

Model hostingu wewnątrz procesu

Projekty domyślne dla modelu hostingu w procesie w ASP.NET Core 3.0 lub nowszym. Opcjonalnie możesz usunąć <AspNetCoreHostingModel> właściwość w pliku projektu, jeśli jego wartość to InProcess.

Kestrel

Konfigurowanie

Migrowanie Kestrel konfiguracji do konstruktora hostów internetowych udostępnianych przez ConfigureWebHostDefaults program (Program.cs):

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        });

Jeśli aplikacja utworzy hosta ręcznie ConfigureWebHost zamiast ConfigureWebHostDefaults, wywołaj metodę UseKestrel w konstruktorze hosta internetowego:

public static void Main(string[] args)
{
    var host = new HostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder.UseKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseIISIntegration()
            .UseStartup<Startup>();
        })
        .Build();

    host.Run();
}

Oprogramowanie pośredniczące Połączenie ion zastępuje adaptery Połączenie ion

Karty Połączenie ion (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter) zostały usunięte z Kestrelprogramu . Zastąp karty Połączenie ion oprogramowaniem pośredniczącym Połączenie ion. oprogramowanie pośredniczące Połączenie ion jest podobne do oprogramowania pośredniczącego HTTP w potoku ASP.NET Core, ale w przypadku połączeń niższego poziomu. Rejestrowanie https i połączeń:

  • Zostały przeniesione z adapterów Połączenie ion do oprogramowania pośredniczącego Połączenie ion.
  • Te metody rozszerzeń działają podobnie jak w poprzednich wersjach ASP.NET Core.

Aby uzyskać więcej informacji, zobacz przykład tlsFilter Połączenie ionHandler w sekcji ListenOptions.Protocols artykułuKestrel.

Abstrakcje transportu zostały przeniesione i upublicznione

Warstwa Kestrel transportu została udostępniona jako interfejs publiczny w programie Connections.Abstractions. W ramach tych aktualizacji:

  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions i skojarzone typy zostały usunięte.
  • NoDelay został przeniesiony z ListenOptions do opcji transportu.
  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode został usunięty z KestrelServerOptions.

Aby uzyskać więcej informacji, zobacz następujące zasoby usługi GitHub:

Kestrel Żądanie nagłówków przyczepy

W przypadku aplikacji przeznaczonych dla wcześniejszych wersji ASP.NET Core:

  • Kestrel Dodaje fragmenty nagłówków przyczepy HTTP/1.1 do kolekcji nagłówków żądań.
  • Przyczepy są dostępne po przeczytaniu treści żądania na końcu.

Powoduje to pewne obawy dotyczące niejednoznaczności między nagłówkami i przyczepami, więc przyczepy zostały przeniesione do nowej kolekcji (RequestTrailerExtensions) w wersji 3.0.

Przyczepy żądań HTTP/2 są następujące:

  • Niedostępne w programie ASP.NET Core 2.2.
  • Dostępne w wersji 3.0 jako RequestTrailerExtensions.

Nowe metody rozszerzenia żądania są obecne w celu uzyskania dostępu do tych przyczep. Podobnie jak w przypadku protokołu HTTP/1.1 przyczepy są dostępne po przeczytaniu treści żądania na końcu.

W wersji 3.0 dostępne są następujące RequestTrailerExtensions metody:

  • GetDeclaredTrailers: Pobiera nagłówek żądania Trailer , który wyświetla listę zwiastunów, których oczekuje się po treści.
  • SupportsTrailers: wskazuje, czy żądanie obsługuje odbieranie nagłówków przyczepy.
  • CheckTrailersAvailable: sprawdza, czy żądanie obsługuje przyczepy i czy są dostępne do odczytania. Ta kontrola nie zakłada, że istnieją zwiastuny do czytania. Nie może być żadnych przyczep do odczytania, nawet jeśli true jest zwracana przez tę metodę.
  • GetTrailer: pobiera żądany nagłówek końcowy z odpowiedzi. Sprawdź SupportsTrailers przed wywołaniem GetTrailermetody lub NotSupportedException może wystąpić, jeśli żądanie nie obsługuje nagłówków końcowych.

Aby uzyskać więcej informacji, zobacz Umieszczanie zwiastunów żądań w oddzielnej kolekcji (dotnet/AspNetCore #10410).

Funkcja AllowSynchronousIO jest wyłączona

AllowSynchronousIO włącza lub wyłącza synchroniczne interfejsy API we/wy, takie jak HttpRequest.Body.Read, HttpResponse.Body.Writei Stream.Flush. Te interfejsy API są źródłem głodu wątku prowadzącego do awarii aplikacji. W wersji 3.0 AllowSynchronousIO jest domyślnie wyłączona. Aby uzyskać więcej informacji, zobacz sekcję Synchroniczne we/wy Kestrel w artykule.

Jeśli wymagane jest synchroniczne operacje we/wy, można ją włączyć, konfigurując AllowSynchronousIO opcję na używanym serwerze (na przykład w ConfigureKestrelprzypadku używania polecenia Kestrel). Należy pamiętać, że wszystkie serwery (Kestrel, HttpSys, TestServer itp.) mają własną AllowSynchronousIO opcję, która nie wpłynie na inne serwery. Synchroniczne operacje we/wy można włączyć dla wszystkich serwerów dla poszczególnych żądań przy użyciu IHttpBodyControlFeature.AllowSynchronousIO opcji :

var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();

if (syncIOFeature != null)
{
    syncIOFeature.AllowSynchronousIO = true;
}

Jeśli masz problemy z implementacjami TextWriter lub innymi strumieniami, które wywołają synchroniczne interfejsy API w funkcji Dispose, wywołaj nowy DisposeAsync interfejs API.

Aby uzyskać więcej informacji, zobacz [Announcement] AllowSynchronousIO disabled in all servers (dotnet/AspNetCore #7644).

Buforowanie formatera danych wyjściowych

Formatery wyjściowe newtonsoft.Json, XmlSerializeri DataContractSerializer oparte na nich obsługują tylko synchroniczną serializacji. Aby umożliwić tym formatatorom pracę z ograniczeniami AllowSynchronousIO serwera, MVC buforuje dane wyjściowe tych formaterów przed zapisem na dysku. W wyniku buforowania mvC będzie zawierać nagłówek Content-Length podczas odpowiadania przy użyciu tych formaterów.

System.Text.Json program obsługuje serializację asynchroniczną, a w związku z tym System.Text.Json program formatujący oparty nie buforuje. Rozważ użycie tego formatnika w celu zwiększenia wydajności.

Aby wyłączyć buforowanie, aplikacje mogą konfigurować SuppressOutputFormatterBuffering podczas uruchamiania:

services.AddControllers(options => options.SuppressOutputFormatterBuffering = true)

Należy pamiętać, że może to spowodować zgłoszenie wyjątku środowiska uruchomieniowego przez aplikację, jeśli AllowSynchronousIO nie zostanie również skonfigurowane.

Microsoft.AspNetCore.Server.Kestrel. Usunięto zestaw HTTPS

W ASP.NET Core 2.1 zawartość pliku Microsoft.AspNetCore.Server.Kestrel. Plik Https.dll został przeniesiony do pliku Microsoft.AspNetCore.Server.Kestrel. Core.dll. Była to aktualizacja niełamiąca się przy użyciu TypeForwardedTo atrybutów. W wersji 3.0 pusty Microsoft.AspNetCore.Server.Kestrel Zestaw Https.dll i pakiet NuGet zostały usunięte.

Biblioteki odwołujące się do microsoft.AspNetCore.Server.Kestrel. Protokół HTTPS powinien zaktualizować zależności ASP.NET Core do wersji 2.1 lub nowszej.

Aplikacje i biblioteki przeznaczone dla platformy ASP.NET Core 2.1 lub nowszej powinny usuwać wszelkie bezpośrednie odwołania do serwera Microsoft.AspNetCore.Server.Kestrel Pakiet HTTPS .

Obsługa pliku Newtonsoft.Json (Json.NET)

W ramach prac nad ulepszeniem platformy udostępnionej ASP.NET Core plik Newtonsoft.Json (Json.NET) został usunięty z udostępnionej platformy ASP.NET Core.

Domyślnym JSserializatorem ON dla ASP.NET Core jest teraz System.Text.Json, który jest nowy na platformie .NET Core 3.0. Rozważ użycie, System.Text.Json jeśli to możliwe. Jest to wysoka wydajność i nie wymaga dodatkowej zależności biblioteki. Jednak ponieważ System.Text.Json jest nowy, obecnie może brakować funkcji, których potrzebuje Twoja aplikacja. Aby uzyskać więcej informacji, zobacz How to migrate from Newtonsoft.Json to System.Text.Json (Jak przeprowadzić migrację z pliku Newtonsoft.Json do pliku System.Text.Json).

Używanie pliku Newtonsoft.Json w projekcie ASP.NET Core 3.0 SignalR

  • Zainstaluj plik Microsoft.AspNetCore.SignalR. Protocols.NewtonsoftJson Pakiet NuGet.

  • Na kliencie połącz wywołanie AddNewtonsoftJsonProtocol metody z wystąpieniem HubConnectionBuilder :

    new HubConnectionBuilder()
        .WithUrl("/chathub")
        .AddNewtonsoftJsonProtocol(...)
        .Build();
    
  • Na serwerze połącz wywołanie AddNewtonsoftJsonProtocol metody z AddSignalR wywołaniem metody w Startup.ConfigureServicespliku :

    services.AddSignalR()
        .AddNewtonsoftJsonProtocol(...);
    

Używanie pliku Newtonsoft.Json w projekcie MVC platformy ASP.NET Core 3.0

  • Zainstaluj pakiet Microsoft.AspNetCore.Mvc.NewtonsoftJson.

  • Zaktualizuj Startup.ConfigureServices polecenie , aby wywołać metodę AddNewtonsoftJson.

    services.AddMvc()
        .AddNewtonsoftJson();
    

    AddNewtonsoftJson jest zgodny z nowymi metodami rejestracji usługi MVC:

    • AddRazorPages
    • AddControllersWithViews
    • AddControllers
    services.AddControllers()
        .AddNewtonsoftJson();
    

    Newtonsoft.Json ustawienia można ustawić w wywołaniu na AddNewtonsoftJson:

    services.AddMvc()
        .AddNewtonsoftJson(options =>
               options.SerializerSettings.ContractResolver =
                  new CamelCasePropertyNamesContractResolver());
    

    Uwaga: jeśli AddNewtonsoftJson metoda jest niedostępna, upewnij się, że pakiet został Microsoft.AspNetCore.Mvc.NewtonsoftJson zainstalowany. Typowym błędem jest zainstalowanie pakietu Newtonsoft.Json zamiast Microsoft.AspNetCore.Mvc.NewtonsoftJson pakietu.

Aby uzyskać więcej informacji, zobacz Dodawanie obsługi formatu ON opartego na JSpliku Newtonsoft.Json.

Rejestracja usługi MVC

ASP.NET Core 3.0 dodaje nowe opcje rejestrowania scenariuszy MVC w programie Startup.ConfigureServices.

Dostępne są trzy nowe metody rozszerzenia najwyższego poziomu związane ze scenariuszami IServiceCollection MVC. Szablony używają tych nowych metod zamiast AddMvc. AddMvc Nadal jednak zachowuje się tak, jak w poprzednich wersjach.

W poniższym przykładzie dodano obsługę kontrolerów i funkcji związanych z interfejsem API, ale nie widoków ani stron. Szablon interfejsu API używa tego kodu:

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

W poniższym przykładzie dodano obsługę kontrolerów, funkcji związanych z interfejsem API i widoków, ale nie stron. Szablon aplikacji internetowej (MVC) używa następującego kodu:

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

W poniższym przykładzie dodano obsługę Razor stron i minimalną obsługę kontrolera. Szablon aplikacji internetowej używa tego kodu:

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

Można również połączyć nowe metody. Poniższy przykład jest odpowiednikiem wywołania AddMvc w programie ASP.NET Core 2.2:

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

Kod uruchamiania routingu

Jeśli aplikacja wywołuje UseMvc metodę lub UseSignalR, zmigruj aplikację do routingu punktu końcowego, jeśli to możliwe. Aby poprawić zgodność routingu punktów końcowych z poprzednimi wersjami wzorca MVC, przywróciliśmy niektóre zmiany generowania adresów URL wprowadzone w ASP.NET Core 2.2. Jeśli wystąpiły problemy z używaniem routingu punktu końcowego w wersji 2.2, należy oczekiwać ulepszeń w programie ASP.NET Core 3.0 z następującymi wyjątkami:

  • Jeśli aplikacja implementuje IRouter lub dziedziczy z Routeelementu , użyj elementu DynamicRouteValuesTransformer jako zamiany.
  • Jeśli aplikacja uzyskuje bezpośredni dostęp do RouteData.Routers wewnątrz wzorca MVC w celu analizowania adresów URL, możesz zamienić tę wartość przy użyciu elementu LinkParser.ParsePathByEndpointName.
    • Zdefiniuj trasę przy użyciu nazwy trasy.
    • Użyj LinkParser.ParsePathByEndpointName i przekaż żądaną nazwę trasy.

Routing punktu końcowego obsługuje tę samą składnię wzorca trasy i funkcje tworzenia wzorca trasy co IRouter. Routing punktów końcowych obsługuje funkcję IRouteConstraint. Routing punktów końcowych obsługuje [Route]atrybuty [HttpGet]routingu MVC , i inne atrybuty routingu MVC.

W przypadku większości aplikacji wymagane są tylko Startup zmiany.

Migrowanie pliku Startup.Configure

Ogólne porady:

  • Dodaj UseRoutingelement .

  • Jeśli aplikacja wywołuje metodę UseStaticFiles, umieść wcześniejUseRoutingUseStaticFiles.

  • Jeśli aplikacja używa funkcji uwierzytelniania/autoryzacji, takich jak AuthorizePage lub , należy umieścić wywołanie do UseAuthentication i UseAuthorization: po i UseRoutingUseCors, ale przed UseEndpoints[Authorize]:

    public void Configure(IApplicationBuilder app)
    {
      ...
    
      app.UseStaticFiles();
    
      app.UseRouting();
      app.UseCors();
    
      app.UseAuthentication();
      app.UseAuthorization();
    
      app.UseEndpoints(endpoints => {
         endpoints.MapControllers();
      });
    
  • Zastąp UseMvc element lub UseSignalR ciągiem UseEndpoints.

  • Jeśli aplikacja używa scenariuszy CORS , takich jak [EnableCors], należy umieścić UseCors wywołanie przed jakimkolwiek innym oprogramowaniem pośredniczącym używającym mechanizmu CORS (na przykład umieścić UseCors przed UseAuthentication, UseAuthorizationi UseEndpoints).

  • Zastąp ciąg IHostingEnvironment ciągiem i IWebHostEnvironment dodaj instrukcję using dla Microsoft.AspNetCore.Hosting przestrzeni nazw.

  • Zastąp ciąg IApplicationLifetime ciągiem IHostApplicationLifetime (Microsoft.Extensions.Hosting przestrzeń nazw).

  • Zastąp ciąg EnvironmentName ciągiem Environments (Microsoft.Extensions.Hosting przestrzeń nazw).

Poniższy kod jest przykładem Startup.Configure typowej aplikacji ASP.NET Core 2.2:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseAuthentication();

    app.UseSignalR(hubs =>
    {
        hubs.MapHub<ChatHub>("/chat");
    });

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

Po zaktualizowaniu poprzedniego Startup.Configure kodu:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseRouting();

    app.UseCors();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chat");
        endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

Ostrzeżenie

W przypadku większości aplikacji wywołania metody UseAuthentication, UseAuthorizationi UseCors muszą pojawiać się między wywołaniami UseRouting i UseEndpoints być skuteczne.

Kontrole kondycji

Testy kondycji używają routingu punktu końcowego z hostem ogólnym. W Startup.Configurepliku wywołaj MapHealthChecks konstruktora punktu końcowego przy użyciu adresu URL punktu końcowego lub ścieżki względnej:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
});

Punkty końcowe kontroli kondycji mogą:

  • Określ co najmniej jeden dozwolony host/porty.
  • Wymagaj autoryzacji.
  • Wymagaj mechanizmu CORS.

Aby uzyskać więcej informacji, zobacz Kontrola kondycji na platformie ASP.NET Core.

Wskazówki dotyczące oprogramowania pośredniczącego zabezpieczeń

Obsługa autoryzacji i mechanizmu CORS jest ujednolicona w przypadku podejścia oprogramowania pośredniczącego. Umożliwia to korzystanie z tego samego oprogramowania pośredniczącego i funkcji w tych scenariuszach. Zaktualizowane oprogramowanie pośredniczące autoryzacji jest dostępne w tej wersji, a oprogramowanie pośredniczące CORS zostało ulepszone, aby zrozumieć atrybuty używane przez kontrolery MVC.

CORS

Wcześniej mechanizm CORS może być trudny do skonfigurowania. Oprogramowanie pośredniczące zostało dostarczone do użytku w niektórych przypadkach użycia, ale filtry MVC miały być używane bez oprogramowania pośredniczącego w innych przypadkach użycia. W przypadku ASP.NET Core 3.0 zalecamy, aby wszystkie aplikacje wymagające mechanizmu CORS korzystały z oprogramowania pośredniczącego CORS w połączeniu z routingiem punktów końcowych. UseCors Można podać domyślne zasady, a [EnableCors][DisableCors] atrybuty mogą służyć do zastępowania domyślnych zasad tam, gdzie jest to wymagane.

W poniższym przykładzie:

  • Mechanizm CORS jest włączony dla wszystkich punktów końcowych z nazwanymi default zasadami.
  • Klasa MyController wyłącza mechanizm CORS z atrybutem [DisableCors] .
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseCors("default");

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

[DisableCors]
public class MyController : ControllerBase
{
    ...
}

Autoryzacja

We wcześniejszych wersjach ASP.NET Core obsługa autoryzacji została udostępniona za pośrednictwem atrybutu [Authorize] . Oprogramowanie pośredniczące autoryzacji nie było dostępne. W programie ASP.NET Core 3.0 wymagane jest oprogramowanie pośredniczące autoryzacji. Zalecamy umieszczenie oprogramowania pośredniczącego ASP.NET Core Authorization Middleware (UseAuthorization) bezpośrednio po .UseAuthentication Oprogramowanie pośredniczące autoryzacji można również skonfigurować przy użyciu zasad domyślnych, które można zastąpić.

W systemie ASP.NET Core 3.0 lub nowszym UseAuthorization jest wywoływana w Startup.Configuresystemie , a użytkownik HomeController zalogowany wymaga następującego konta:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

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

public class HomeController : Controller
{
    [Authorize]
    public IActionResult BuyWidgets()
    {
        ...
    }
}

W przypadku korzystania z routingu punktu końcowego zalecamy skonfigurowanie AuthorizeFilter oprogramowania pośredniczącego autoryzacji i zamiast tego poleganie na programie pośredniczącym autoryzacji. Jeśli aplikacja używa filtru AuthorizeFilter globalnego w mvC, zalecamy refaktoryzowanie kodu w celu udostępnienia zasad w wywołaniu metody AddAuthorization.

Element DefaultPolicy jest początkowo skonfigurowany do wymagania uwierzytelniania, więc nie jest wymagana żadna dodatkowa konfiguracja. W poniższym przykładzie punkty końcowe MVC są oznaczone jako RequireAuthorization tak, aby wszystkie żądania były autoryzowane na podstawie elementu DefaultPolicy. Jednak zezwala na HomeController dostęp bez logowania użytkownika do aplikacji z powodu :[AllowAnonymous]

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute().RequireAuthorization();
    });
}

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

Autoryzacja dla określonych punktów końcowych

Autoryzację można również skonfigurować dla określonych klas punktów końcowych. Poniższy kod to przykład konwertowania aplikacji MVC, która skonfigurowała aplikację globalną AuthorizeFilter do aplikacji z określonymi zasadami wymagającymi autoryzacji:

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

    static readonly string _RequireAuthenticatedUserPolicy = 
                            "RequireAuthenticatedUserPolicy";
    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        // Pre 3.0:
        // services.AddMvc(options => options.Filters.Add(new AuthorizeFilter(...));

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(o => o.AddPolicy(_RequireAuthenticatedUserPolicy,
                        builder => builder.RequireAuthenticatedUser()));

    }

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

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

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

Można również dostosować zasady. Skonfigurowano DefaultPolicy opcję wymagania uwierzytelniania:

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

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
              .RequireAuthenticatedUser()
              .Build();
        });

    }

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

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute().RequireAuthorization();
            endpoints.MapRazorPages();
        });
    }
}
[AllowAnonymous]
public class HomeController : Controller
{

Alternatywnie można skonfigurować wszystkie punkty końcowe tak, aby wymagały autoryzacji bez [Authorize]RequireAuthorization lub przez skonfigurowanie elementu FallbackPolicy. Wartość FallbackPolicy różni się od elementu DefaultPolicy. Element DefaultPolicy jest wyzwalany przez [Authorize] element lub RequireAuthorization, gdy FallbackPolicy parametr jest wyzwalany, gdy nie ustawiono żadnych innych zasad. FallbackPolicy jest początkowo skonfigurowany do zezwalania na żądania bez autoryzacji.

Poniższy przykład jest taki sam jak w poprzednim DefaultPolicy przykładzie, ale używa elementu FallbackPolicy , aby zawsze wymagać uwierzytelniania we wszystkich punktach końcowych, z wyjątkiem sytuacji, gdy [AllowAnonymous] jest określona:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddAuthorization(options =>
    {
        options.FallbackPolicy = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();
    });
}

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

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

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

Autoryzacja przez oprogramowanie pośredniczące działa bez posiadania żadnej konkretnej wiedzy na temat autoryzacji. Na przykład testy kondycji nie mają określonej wiedzy na temat autoryzacji, ale testy kondycji mogą mieć konfigurowalne zasady autoryzacji stosowane przez oprogramowanie pośredniczące.

Ponadto każdy punkt końcowy może dostosować wymagania dotyczące autoryzacji. W poniższym przykładzie UseAuthorization procesów autoryzacji za pomocą DefaultPolicyelementu , ale punkt końcowy sprawdzania /healthz kondycji wymaga admin użytkownika:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints
            .MapHealthChecks("/healthz")
            .RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin", });
    });
}

Ochrona jest implementowana w niektórych scenariuszach. Oprogramowanie pośredniczące punktów końcowych zgłasza wyjątek, jeśli pominięto zasady autoryzacji lub mechanizmu CORS z powodu braku oprogramowania pośredniczącego. Obsługa analizatora w celu przekazania dodatkowych opinii na temat błędnej konfiguracji jest w toku.

Niestandardowe programy obsługi autoryzacji

Jeśli aplikacja używa niestandardowych procedur obsługi autoryzacji, routing punktu końcowego przekazuje inny typ zasobu do procedur obsługi niż MVC. Procedury obsługi, które oczekują, że zasób kontekstu procedury obsługi autoryzacji ma być typu AuthorizationFilterContext (typ zasobu dostarczony przez filtry MVC) będzie musiał zostać zaktualizowany w celu obsługi zasobów typu RouteEndpoint (typu zasobu podanego do procedur obsługi autoryzacji według routingu punktu końcowego).

MvC nadal używa AuthorizationFilterContext zasobów, więc jeśli aplikacja używa filtrów autoryzacji MVC wraz z autoryzacją routingu punktu końcowego, może być konieczne do obsługi obu typów zasobów.

SignalR

Mapowanie koncentratorów SignalR odbywa się teraz wewnątrz UseEndpointselementu .

Mapuj każde centrum za pomocą MapHubpolecenia . Podobnie jak w poprzednich wersjach, każde centrum jest jawnie wymienione.

W poniższym przykładzie dodano obsługę ChatHubSignalR centrum:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>();
    });
}

Istnieje nowa opcja kontrolowania limitów rozmiaru komunikatów od klientów. Na przykład w pliku Startup.ConfigureServices:

services.AddSignalR(hubOptions =>
{
    hubOptions.MaximumReceiveMessageSize = 32768;
});

W systemie ASP.NET Core 2.2 można ustawić TransportMaxBufferSize elementy i, które skutecznie kontrolują maksymalny rozmiar komunikatu. W ASP.NET Core 3.0 ta opcja kontroluje teraz tylko maksymalny rozmiar przed zaobserwowanym działaniem wstecznym.

SignalR zestawy w strukturze udostępnionej

zestawy ASP.NET Core SignalR po stronie serwera są teraz instalowane przy użyciu zestawu .NET Core SDK. Aby uzyskać więcej informacji, zobacz Usuwanie przestarzałych odwołań do pakietu w tym dokumencie.

Kontrolery MVC

Mapowanie kontrolerów odbywa się teraz wewnątrz UseEndpointselementu .

Dodaj MapControllers , jeśli aplikacja używa routingu atrybutów. Ponieważ routing obejmuje obsługę wielu platform w programie ASP.NET Core 3.0 lub nowszym, dodanie kontrolerów kierowanych atrybutami jest opt-in.

Zastąp następujące elementy:

  • MapRoute Z MapControllerRoute
  • MapAreaRoute Z MapAreaControllerRoute

Ponieważ routing obejmuje teraz obsługę więcej niż tylko WZORCA MVC, terminologia zmieniła się, aby te metody wyraźnie określały, co robią. Konwencjonalne trasy, takie jakMapControllerRoute//MapAreaControllerRouteMapDefaultControllerRoute, są stosowane w kolejności, w której są dodawane. Najpierw umieść bardziej szczegółowe trasy (takie jak trasy dla obszaru).

W poniższym przykładzie:

  • MapControllers Dodaje obsługę kontrolerów kierowanych atrybutami.
  • MapAreaControllerRoute dodaje tradycyjną trasę dla kontrolerów w danym obszarze.
  • MapControllerRoute dodaje tradycyjną trasę dla kontrolerów.
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapAreaControllerRoute(
            "admin",
            "admin",
            "Admin/{controller=Home}/{action=Index}/{id?}");
        endpoints.MapControllerRoute(
            "default", "{controller=Home}/{action=Index}/{id?}");
    });
}

Usuwanie sufiksu asynchronicznego z nazw akcji kontrolera

W ASP.NET Core 3.0 ASP.NET Core MVC usuwa sufiks Async z nazw akcji kontrolera. To nowe ustawienie ma wpływ zarówno na routing, jak i generowanie linków. Na przykład:

public class ProductsController : Controller
{
    public async Task<IActionResult> ListAsync()
    {
        var model = await _dbContext.Products.ToListAsync();
        return View(model);
    }
}

Przed ASP.NET Core 3.0:

  • Dostęp do poprzedniej akcji można uzyskać na trasie Products/ListAsync .

  • Wymagana generacja łącza określająca Async sufiks. Na przykład:

    <a asp-controller="Products" asp-action="ListAsync">List</a>
    

W programie ASP.NET Core 3.0:

  • Dostęp do poprzedniej akcji można uzyskać na trasie Products/List .

  • Generowanie linków nie wymaga określenia sufiksu Async . Na przykład:

    <a asp-controller="Products" asp-action="List">List</a>
    

Ta zmiana nie ma wpływu na nazwy określone przy użyciu atrybutu [ActionName] . Zachowanie domyślne można wyłączyć przy użyciu następującego kodu w pliku Startup.ConfigureServices:

services.AddMvc(options =>
    options.SuppressAsyncSuffixInActionNames = false);

Istnieją pewne różnice w generowaniu linków (na przykład przy użyciu Url.Link i podobnych interfejsów API). Są to:

  • Domyślnie w przypadku korzystania z routingu punktu końcowego wielkość liter parametrów trasy w wygenerowanych identyfikatorach URI nie musi być zachowywana. To zachowanie można kontrolować za pomocą interfejsu IOutboundParameterTransformer .
  • Wygenerowanie identyfikatora URI dla nieprawidłowej trasy (kontrolera/akcji lub strony, która nie istnieje) spowoduje wygenerowanie pustego ciągu w routingu punktu końcowego zamiast tworzenia nieprawidłowego identyfikatora URI.
  • Wartości otoczenia (parametry trasy z bieżącego kontekstu) nie są automatycznie używane w generowaniu linków z routingiem punktów końcowych. Wcześniej podczas generowania linku do innej akcji (lub strony) nieokreślone wartości tras byłyby wnioskowane z bieżących wartości otoczenia tras. W przypadku korzystania z routingu punktu końcowego wszystkie parametry trasy muszą być określone jawnie podczas generowania linków.

Razor Pages

Strony mapowania Razor są teraz dostępne wewnątrz UseEndpointselementu .

Dodaj MapRazorPages , jeśli aplikacja używa Razor stron. Ponieważ routing punktów końcowych obejmuje obsługę wielu struktur, dodawanie Razor stron jest teraz opt-in.

W poniższej Startup.Configure metodzie MapRazorPages dodano obsługę stron Razor :

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

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

Używanie wzorca MVC bez routingu punktu końcowego

Używanie wzorca MVC za pośrednictwem programu UseMvc lub UseMvcWithDefaultRoute w programie ASP.NET Core 3.0 wymaga jawnego wyrażenia zgody wewnątrz Startup.ConfigureServices. Jest to wymagane, ponieważ mvC musi wiedzieć, czy może polegać na autoryzacji i oprogramowania pośredniczącego CORS podczas inicjowania. Analizator jest dostarczany, który ostrzega, jeśli aplikacja próbuje użyć nieobsługiwanej konfiguracji.

Jeśli aplikacja wymaga starszej IRouter obsługi, wyłącz EnableEndpointRouting użycie dowolnego z następujących metod w programie Startup.ConfigureServices:

services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddControllers(options => options.EnableEndpointRouting = false);
services.AddControllersWithViews(options => options.EnableEndpointRouting = false);
services.AddRazorPages().AddMvcOptions(options => options.EnableEndpointRouting = false);

Kontrole kondycji

Testy kondycji mogą być używane jako oprogramowanie routera z routingiem punktów końcowych.

Dodaj MapHealthChecks polecenie , aby używać kontroli kondycji z routingiem punktów końcowych. Metoda MapHealthChecks akceptuje argumenty podobne do UseHealthChecks. Zaletą używania MapHealthChecksUseHealthChecks jest możliwość stosowania autoryzacji i większej precyzyjnej kontroli nad pasującymi zasadami.

W poniższym przykładzie MapHealthChecks jest wywoływana dla punktu końcowego kontroli kondycji pod adresem /healthz:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/healthz", new HealthCheckOptions() { });
    });
}

HostBuilder zastępuje element WebHostBuilder

Szablony ASP.NET Core 3.0 używają hosta ogólnego. Poprzednie wersje używały hosta sieci Web. Poniższy kod przedstawia wygenerowaną Program klasę szablonu ASP.NET Core 3.0:

// requires using Microsoft.AspNetCore.Hosting;
// requires using Microsoft.Extensions.Hosting;

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>();
            });
}

Poniższy kod przedstawia klasę wygenerowaną Program przez szablon ASP.NET Core 2.2:

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

IWebHostBuilder pozostaje w wersji 3.0 i jest typem webBuilder widocznym w poprzednim przykładzie kodu. WebHostBuilder zostanie wycofany w przyszłej wersji i zastąpiony przez HostBuilder.

Najważniejszą zmianą z WebHostBuilder to HostBuilder jest wstrzykiwanie zależności (DI). W przypadku korzystania z programu HostBuildermożna wstrzyknąć tylko następujące polecenie do Startupkonstruktora :

Ograniczenia HostBuilder di:

  • Włącz kompilowania kontenera DI tylko raz.
  • Unika wynikowych problemów z okresem istnienia obiektu, takich jak rozwiązywanie wielu wystąpień pojedynczych wystąpień.

Aby uzyskać więcej informacji, zobacz Unikanie iniekcji usługi uruchamiania w programie ASP.NET Core 3.

DodawanieAuthorization przeniesiono do innego zestawu

Metody ASP.NET Core 2.2 i niższe AddAuthorization w bibliotece Microsoft.AspNetCore.Authorization.dll:

  • Zmieniono AddAuthorizationCorenazwę .
  • Zostały przeniesione do biblioteki Microsoft.AspNetCore.Authorization.Policy.dll.

Nie mają wpływu na aplikacje korzystające zarówno z bibliotek Microsoft.AspNetCore.Authorization.dll , jak i Microsoft.AspNetCore.Authorization.Policy.dll .

Aplikacje, które nie korzystają z biblioteki Microsoft.AspNetCore.Authorization.Policy.dll , powinny wykonywać jedną z następujących czynności:

  • Dodaj odwołanie do biblioteki Microsoft.AspNetCore.Authorization.Policy.dll. To podejście działa w przypadku większości aplikacji i jest to wszystko, co jest wymagane.
  • Przełączanie do używania AddAuthorizationCore

Aby uzyskać więcej informacji, zobacz Zmiana powodująca niezgodność w AddAuthorization(o =>systemie ) przeciążenie życia w innym zestawie #386.

Identity Interfejsu użytkownika

Identity Aktualizacje interfejsu użytkownika dla ASP.NET Core 3.0:

  • Dodaj odwołanie do pakietu do pliku Microsoft.AspNetCore.Identity. Interfejs użytkownika.
  • Aplikacje, które nie używają Razor stron, muszą wywoływać metodę MapRazorPages. Zobacz Razor Strony w tym dokumencie.
  • Bootstrap 4 jest domyślną strukturą interfejsu użytkownika. IdentityUIFrameworkVersion Ustaw właściwość projektu, aby zmienić wartość domyślną. Aby uzyskać więcej informacji, zobacz ten anons usługi GitHub.

SignalR

Klient SignalR języka JavaScript zmienił się z @aspnet/signalr na @microsoft/signalr. Aby zareagować na tę zmianę, zmień odwołania w package.json plikach, require instrukcjach i instrukcjach ECMAScript import .

System.Text.Json jest protokołem domyślnym

System.Text.Json jest teraz domyślnym protokołem koncentratora używanym zarówno przez klienta, jak i serwer.

W Startup.ConfigureServicespliku wywołaj metodę AddJsonProtocol , aby ustawić opcje serializatora.

Serwer:

services.AddSignalR(...)
        .AddJsonProtocol(options =>
        {
            options.PayloadSerializerOptions.WriteIndented = false;
        })

Klient:

new HubConnectionBuilder()
    .WithUrl("/chathub")
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerOptions.WriteIndented = false;
    })
    .Build();

Przełączanie do pliku Newtonsoft.Json

Jeśli używasz funkcji pliku Newtonsoft.Json, które nie są obsługiwane w pliku System.Text.Json, możesz przełączyć się z powrotem na Newtonsoft.Json. Zobacz Use Newtonsoft.Json in an ASP.NET Core 3.0 project (Używanie pliku Newtonsoft.Json w projekcie ASP.NET Core 3.0 SignalR wcześniej w tym artykule).

Rozproszone pamięci podręczne Redis

Microsoft.Extensions.Buforowanie. Pakiet Redis nie jest dostępny dla aplikacji ASP.NET Core 3.0 lub nowszych. Zastąp odwołanie do pakietu microsoft.Extensions.Buforowanie. StackExchangeRedis. Aby uzyskać więcej informacji, zobacz Buforowanie rozproszone w usłudze ASP.NET Core.

Wyrażanie zgody na kompilację środowiska uruchomieniowego

Przed ASP.NET Core 3.0 kompilacja widoków w czasie wykonywania była niejawną funkcją platformy. Kompilacja środowiska uruchomieniowego uzupełnia kompilację widoków w czasie kompilacji. Umożliwia ona kompilowanie widoków i stron (.cshtmlplików) podczas modyfikowania plików bez konieczności ponownego kompilowania Razor całej aplikacji. Ta funkcja obsługuje scenariusz szybkiego edytowania w środowisku IDE i odświeżania przeglądarki w celu wyświetlenia zmian.

W wersji ASP.NET Core 3.0 kompilacja środowiska uruchomieniowego jest scenariuszem z wyrażeniem zgody. Kompilacja w czasie kompilacji to jedyny mechanizm kompilacji widoku, który jest domyślnie włączony. Środowisko uruchomieniowe korzysta z programu Visual Studio lub dotnet-watch w programie Visual Studio Code, aby ponownie skompilować projekt podczas wykrywania zmian w .cshtml plikach. W programie Visual Studio zmienia się na .cs, .cshtmllub .razor pliki w uruchamianym projekcie (Ctrl+F5), ale nie debugowane (F5), wyzwalaj ponowną kompilację projektu.

Aby włączyć kompilację środowiska uruchomieniowego w projekcie ASP.NET Core 3.0:

  1. Zainstaluj plik Microsoft.AspNetCore.Mvc.Razor. RuntimeCompilation pakiet NuGet.

  2. Zaktualizuj Startup.ConfigureServices polecenie , aby wywołać polecenie AddRazorRuntimeCompilation:

    W przypadku ASP.NET Core MVC użyj następującego kodu:

    services.AddControllersWithViews()
        .AddRazorRuntimeCompilation(...);
    

    W przypadku ASP.NET Core Razor Pages użyj następującego kodu:

    services.AddRazorPages()
        .AddRazorRuntimeCompilation(...);
    

W przykładzie pokazano https://github.com/aspnet/samples/tree/main/samples/aspnetcore/mvc/runtimecompilation przykład włączania kompilacji środowiska uruchomieniowego warunkowo w środowiskach deweloperskich.

Aby uzyskać więcej informacji na Razor temat kompilacji plików, zobacz Razor kompilację plików w programie ASP.NET Core.

Migrowanie bibliotek za pomocą wielu elementów docelowych

Biblioteki często muszą obsługiwać wiele wersji ASP.NET Core. Większość bibliotek skompilowanych w poprzednich wersjach ASP.NET Core powinna nadal działać bez problemów. Następujące warunki wymagają, aby aplikacja została skompilowana krzyżowo:

  • Biblioteka opiera się na funkcji, która ma binarną zmianę powodującą niezgodność.
  • Biblioteka chce korzystać z nowych funkcji w ASP.NET Core 3.0.

Na przykład:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netcoreapp3.0;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" />
  </ItemGroup>
</Project>

Użyj #ifdefs polecenia , aby włączyć interfejsy API specyficzne dla platformy ASP.NET Core 3.0:

var webRootFileProvider =
#if NETCOREAPP3_0
    GetRequiredService<IWebHostEnvironment>().WebRootFileProvider;
#elif NETSTANDARD2_0
    GetRequiredService<IHostingEnvironment>().WebRootFileProvider;
#else
#error unknown target framework
#endif

Aby uzyskać więcej informacji na temat używania interfejsów API ASP.NET Core w bibliotece klas, zobacz Use ASP.NET Core APIs in a class library (Używanie interfejsów API ASP.NET Core w bibliotece klas).

Różne zmiany

System weryfikacji w programie .NET Core 3.0 lub nowszym traktuje parametry niepuste lub powiązane właściwości tak, jakby miały [Required] atrybut. Aby uzyskać więcej informacji, zobacz [Wymagany] atrybut.

Publikowanie

Usuń foldery bin i obj w katalogu projektu.

Testserver

W przypadku aplikacji, które używają TestServer bezpośrednio z hostem ogólnym, utwórz element TestServer w obiekcie IWebHostBuilder w ConfigureWebHostpliku :

[Fact]
public async Task GenericCreateAndStartHost_GetTestServer()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .Configure(app => { });
        })
    .StartAsync();

    var response = await host.GetTestServer().CreateClient().GetAsync("/");

    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

Istotne zmiany interfejsu API

Przejrzyj zmiany powodujące niezgodność:

Routing punktów końcowych z parametrem catch-all

Ostrzeżenie

Parametr catch-all może być niepoprawnie zgodny z trasami z powodu błędu w routingu. Aplikacje, których dotyczy ta usterka, mają następujące cechy:

  • Trasa typu catch-all, na przykład {**slug}"
  • Trasa catch-all nie pasuje do żądań, które powinna być zgodna.
  • Usunięcie innych tras sprawia, że trasa catch-all zacznie działać.

Zobacz Usterki usługi GitHub 18677 i 16579 , na przykład przypadki, w których wystąpiła ta usterka.

Poprawka zgody na tę usterkę jest zawarta w zestawie .NET Core 3.1.301 SDK i nowszych wersjach. Poniższy kod ustawia przełącznik wewnętrzny, który naprawia tę usterkę:

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

Platforma .NET Core 3.0 w usłudze aplikacja systemu Azure

Wdrożenie platformy .NET Core w usłudze aplikacja systemu Azure zostało zakończone. Platforma .NET Core 3.0 jest dostępna we wszystkich centrach danych usługi aplikacja systemu Azure.

ASP.NET Core Module (ANCM)

Jeśli moduł ASP.NET Core Module (ANCM) nie był wybranym składnikiem, gdy program Visual Studio został zainstalowany lub czy wcześniejsza wersja narzędzia ANCM została zainstalowana w systemie, pobierz najnowszy Instalator pakietu hostingowego platformy .NET Core (pobieranie bezpośrednie) i uruchom instalatora. Aby uzyskać więcej informacji, zobacz Hosting Bundle (Pakiet hostingu).