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. Pomocne może być utworzenie nowego projektu 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 pliku global.json

Jeśli twoje rozwiązanie opiera się na pliku global.json w celu kierowania określonej wersji zestawu SDK platformy .NET Core, 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 element Target Framework Moniker (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 ASP.NET Core 3.0. Takie odwołania do pakietu powinny zostać usunięte z pliku projektu. Rozważmy 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>:

    • Aktualizuje program TFM do netcoreapp3.0
    • Usuwa <AspNetCoreHostingModel> 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 jest usuwany i na poniższej liście pakietów nie są już generowane.

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ż generowane
  • Microsoft.AspNetCore
  • Microsoft.AspNetCore.All
  • Microsoft.AspNetCore.App
  • Microsoft.AspNetCore.Antiforgery
  • Microsoft.AspNetCore.Authentication
  • Microsoft.AspNetCore.Authentication.Abstractions
  • Microsoft.AspNetCore.Authentication.Cookie S
  • Microsoft.AspNetCore.Authentication.Core
  • Microsoft.AspNetCore.Authentication.OAuth
  • Microsoft.AspNetCore.Authorization.Policy
  • Microsoft.AspNetCore.Cookie Zasad
  • 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.Razor Stron
  • 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 struktury

Funkcje ASP.NET Core, które były dostępne za pośrednictwem jednego z wymienionych powyżej pakietów, są dostępne w ramach struktury udostępnionejMicrosoft.AspNetCore.App. Platforma udostępniona to zestaw zestawów (.dll plików), które są instalowane 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 .

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

    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
        ...
    </Project>
    
  • Projekty, które są przeznaczone dla elementu docelowego Microsoft.NET.Sdk lub Microsoft.NET.Sdk.Razor zestawu SDK, powinny dodać jawne FrameworkReference polecenie 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 platformy Framework przy użyciu platformy Docker

Kompilacje zależne od struktury aplikacji konsolowych, które korzystają 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.Appto udostępniona struktura zawierająca środowisko uruchomieniowe ASP.NET Core i jest obecna tylko na obrazie dotnet/core/aspnet Docker. Zestaw SDK w wersji 3.0 zmniejsza rozmiar kompilacji zależnych od platformy przy użyciu ASP.NET Core, nie uwzględniają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 określić, 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. Poniższy plik JSON 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, odwołaj 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 pokazuje 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 poprzedniej ilustracji dodany kod jest wyświetlany na zielono. Aby uzyskać informacje na temat następujących zmian:

Obsługa analizatora

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

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

<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 mvC, muszą ustawić AddRazorSupportForMvc właściwość w pliku projektu:

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

Model hostingu w procesie

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 sieci Web dostarczonego 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 ręcznie utworzy hosta ConfigureWebHost zamiast ConfigureWebHostDefaults, wywołaj polecenie UseKestrel w konstruktorze hostów sieci Web:

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łączenia zastępuje karty połączenia

Karty połączenia (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter) zostały usunięte z Kestrelprogramu . Zastąp karty połączenia oprogramowaniem pośredniczącym połączenia. Oprogramowanie pośredniczące połączeń 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 kart połączenia do oprogramowania pośredniczącego połączenia.
  • Te metody rozszerzenia działają tak jak w poprzednich wersjach ASP.NET Core.

Aby uzyskać więcej informacji, zobacz przykład tlsFilterConnectionHandler w sekcji ListenOptions.Protocols w Kestrel artykule.

Abstrakcje transportu zostały przeniesione i upublicznione

Warstwa Kestrel transportu została uwidoczniona 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 KestrelServerOptionselementu .

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

Kestrel Żądanie nagłówków przyczepy

W przypadku aplikacji przeznaczonych dla starszych wersji ASP.NET Core:

  • Kestrel Dodaje fragmentowane nagłówki 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 to:

  • Niedostępne w 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 odczytaniu 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 zawiera listę zwiastunów, których można oczekiwać 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. To sprawdzenie nie zakłada, że istnieją przyczepy do czytania. Nie ma zwiastunów 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 metody GetTrailerlub 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).

Ustawienie AllowSynchronousIO wyłączone

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ę Synchroniczna we/wy w Kestrel 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 przypadku ConfigureKestrelużywania metody 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 na żądanie 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 metodzie Dispose, wywołaj nowy DisposeAsync interfejs API.

Aby uzyskać więcej informacji, zobacz [Anons] AllowSynchronousIO wyłączone we wszystkich serwerach (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 obsługuje asynchroniczną serializacji, 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ć, że aplikacja zgłasza wyjątek środowiska uruchomieniowego, jeśli AllowSynchronousIO nie jest również skonfigurowana.

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

W ASP.NET Core 2.1 zawartość pliku Microsoft.AspNetCore.Server.Kestrel. Https.dll zostały przeniesione do witryny Microsoft.AspNetCore.Server.Kestrel. Core.dll. Była to aktualizacja niezgodna przy użyciu TypeForwardedTo atrybutów. W przypadku wersji 3.0 pusty plik Microsoft.AspNetCore.Server.Kestrel. Https.dll zestaw i pakiet NuGet zostały usunięte.

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

Aplikacje i biblioteki przeznaczone dla ASP.NET Core 2.1 lub nowszego 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 struktury udostępnionej ASP.NET Coreplik Newtonsoft.Json (Json.NET) został usunięty z platformy udostępnionej ASP.NET Core.

Domyślny serializator JSON dla ASP.NET Core to teraz System.Text.Json, czyli nowy w programie .NET Core 3.0. Rozważ użycie, System.Text.Json jeśli jest 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 NuGet package.

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

    new HubConnectionBuilder()
        .WithUrl("/chathub")
        .AddNewtonsoftJsonProtocol(...)
        .Build();
    
  • Na serwerze połącz AddNewtonsoftJsonProtocol łańcuch wywołania metody z AddSignalR wywołaniem metody w pliku Startup.ConfigureServices:

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

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

  • Zainstaluj pakiet Microsoft.AspNetCore.Mvc.NewtonsoftJson.

  • Zaktualizuj polecenie Startup.ConfigureServices , 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:AddNewtonsoftJson Jeśli metoda nie jest dostępna, upewnij się, że zainstalowano Microsoft.AspNetCore.Mvc.NewtonsoftJson pakiet. Typowym błędem jest zainstalowanie pakietu Newtonsoft.Json zamiast Microsoft.AspNetCore.Mvc.NewtonsoftJson pakietu.

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

Rejestracja usługi MVC

ASP.NET Core 3.0 dodaje nowe opcje rejestrowania scenariuszy MVC wewnątrz Startup.ConfigureServicesprogramu .

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

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

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

Kod uruchamiania routingu

Jeśli aplikacja wywołuje metodę UseMvc lub UseSignalR, zmigruj aplikację do routingu punktów końcowych , jeśli to możliwe. Aby poprawić zgodność routingu punktów końcowych z poprzednimi wersjami 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życiem routingu punktów końcowych w wersji 2.2, należy oczekiwać ulepszeń w wersji ASP.NET Core 3.0 z następującymi wyjątkami:

  • Jeśli aplikacja implementuje IRouter lub dziedziczy z Routeklasy , użyj elementu DynamicRouteValuesTransformer jako zamiany.
  • Jeśli aplikacja uzyskuje bezpośredni dostęp do RouteData.Routers niej w celu analizowania adresów URL, możesz zastąpić tę wartością za pomocą parametru 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 punktu końcowego obsługuje usługę IRouteConstraint. Routing punktu końcowego obsługuje [Route]atrybuty routingu MVC , [HttpGet]i inne.

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ść UseStaticFilesprzedUseRouting.

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

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

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

  • Zastąp IHostingEnvironment ciąg i IWebHostEnvironment dodaj instrukcję using dla Microsoft.Extensions.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 i UseRoutingUseEndpoints być skuteczne.

Kontrole kondycji

Testy kondycji używają routingu punktu końcowego z hostem ogólnym. W Startup.Configureprogramie wywołaj MapHealthChecks konstruktora punktów końcowych 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 Sprawdzanie kondycji w ASP.NET Core.

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

Obsługa autoryzacji i mechanizmu CORS jest ujednolicona wokół 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 udostępniane w tej wersji, a oprogramowanie pośredniczące CORS jest rozszerzone, 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 używały oprogramowania pośredniczącego CORS w połączeniu z routingiem punktów końcowych. UseCors można podać zasady domyślne, 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 zasadami default .
  • 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 ASP.NET Core 3.0 wymagane jest oprogramowanie pośredniczące autoryzacji. Zalecamy umieszczenie oprogramowania pośredniczącego autoryzacji ASP.NET Core (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 ASP.NET Core w wersji 3.0 lub nowszej UseAuthorization jest wywoływana w Startup.Configuresystemie , a następujące HomeController wymagania wymagają zalogowanego użytkownika:

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 punktów końcowych zalecamy skonfigurowanie AuthorizeFilter oprogramowania pośredniczącego autoryzacji i zamiast tego polegać na tym, aby używać oprogramowania pośredniczącego 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 tak, aby wymagał 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 DefaultPolicypodstawie elementu . 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 globalną AuthorizeFilter aplikację 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();
        });
    }
}

Zasady można również dostosować. 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 wszystkie punkty końcowe można skonfigurować tak, aby wymagały autoryzacji bez [Authorize] lub RequireAuthorization przez skonfigurowanie FallbackPolicyelementu . Wartość FallbackPolicy różni się od elementu DefaultPolicy. Element DefaultPolicy jest wyzwalany przez [Authorize] element lub RequireAuthorization, gdy FallbackPolicy element 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, w których [AllowAnonymous] określono:

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 konkretnej wiedzy na temat autoryzacji. Na przykład testy kondycji nie mają konkretnej wiedzy na temat autoryzacji, ale kontrole 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ą elementu DefaultPolicy, 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 przekazywania dodatkowych informacji zwrotnych 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, aby obsłużyć zasoby typu RouteEndpoint (typ zasobu przydzielony do procedur obsługi autoryzacji przez routing 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 obsłużenie obu typów zasobów.

SignalR

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

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

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

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 Startup.ConfigureServicespliku :

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

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

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 struktur w ASP.NET Core 3.0 lub nowszych, 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 MVC, terminologia zmieniła się, aby te metody jasno określały, co robią. Konwencjonalne trasy, takie jak MapControllerRoute//MapAreaControllerRouteMapDefaultControllerRoute są stosowane w kolejności ich dodawania. 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 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 Async sufiks z nazw akcji kontrolera. Na to nowe ustawienie ma wpływ zarówno 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ć w trasie Products/ListAsync .

  • Wymagane generowanie linków Async określające sufiks. Na przykład:

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

W 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] . Domyślne zachowanie można wyłączyć przy użyciu następującego kodu w Startup.ConfigureServicespliku :

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ą one następujące:

  • 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 utworzenia 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ć jawnie określone podczas generowania linków.

Razor Stron

Strony mapowania Razor są teraz wykonywane wewnątrz UseEndpointselementu .

Dodaj MapRazorPages , jeśli aplikacja używa Razor stron. Ponieważ routing punktów końcowych obejmuje obsługę wielu struktur, dodanie 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 punktów końcowych

Korzystanie ze wzorca MVC za pośrednictwem lub UseMvcUseMvcWithDefaultRoute w ASP.NET Core 3.0 wymaga jawnego wyrażenia zgody w programie 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

Kontrole 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 MapHealthChecks funkcji over UseHealthChecks jest możliwość stosowania autoryzacji i większej precyzyjnej kontroli nad pasującymi zasadami.

W poniższym przykładzie MapHealthChecks element jest wywoływany dla punktu końcowego kontroli kondycji w lokalizacji /healthz:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

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

HostBuilder zastępuje 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 szablony 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.

Najbardziej znaczącą zmianą z WebHostBuilder na 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.
  • Pozwala uniknąć 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 ASP.NET Core 3.

DodawanieAuthorization przeniesiono do innego zestawu

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

  • Zmieniono nazwę AddAuthorizationCore.
  • Zostały przeniesione do Microsoft.AspNetCore.Authorization.Policy.dll.

Nie ma to wpływu na aplikacje korzystające zarówno z Microsoft.AspNetCore.Authorization.dll, jak iMicrosoft.AspNetCore.Authorization.Policy.dll .

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

  • Dodaj odwołanie do 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 Breaking change in AddAuthorization(o =>) przeciążenie życia w innym zestawie #386.

Identity INTERFEJSU UŻYTKOWNIKA

IdentityAktualizacje interfejsu użytkownika dla ASP.NET Core 3.0:

SignalR

Klient SignalR 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.

Serwera:

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

Klienta:

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

Przełączanie do pliku Newtonsoft.Json

Jeśli używasz funkcji pakietu Newtonsoft.Json, które nie są obsługiwane w pliku System.Text.Json, możesz wrócić do Newtonsoft.Jsonpliku . 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 we wcześniejszej sekcji tego artykułu.

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 Rozproszone buforowanie w 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ą struktury. 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 ASP.NET Core 3.0 kompilacja środowiska uruchomieniowego jest scenariuszem zgody. Kompilacja w czasie kompilacji jest jedynym mechanizmem kompilacji widoku, który jest domyślnie włączony. Środowisko uruchomieniowe opiera się na Visual Studio lub dotnet-watch w Visual Studio Code, aby ponownie skompilować projekt po wykryciu zmian w .cshtml plikach. W Visual Studio zmiany w .csplikach , .cshtmllub .razor 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 NuGet pakiet.

  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 warunkowego włączania kompilacji środowiska uruchomieniowego w środowiskach deweloperskich.

Aby uzyskać więcej informacji na Razor temat kompilacji plików, zobacz Razor kompilację plików w 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:

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 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 sprawdzania poprawności 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 elem.IWebHostBuilderConfigureWebHost

[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 usterki routingu. Aplikacje, których dotyczy ten błąd, mają następujące cechy:

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

Zobacz GitHub usterek 18677 i 16579, na przykład przypadków, które uderzyły w tę usterkę.

Poprawka zgody na tę usterkę jest zawarta w zestawie SDK platformy .NET Core 3.1.301 i nowszym. 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 Azure App Service

Wdrożenie platformy .NET Core w celu Azure App Service zostało zakończone. Platforma .NET Core 3.0 jest dostępna we wszystkich centrach danych Azure App Service.

moduł ASP.NET Core (ANCM)

Jeśli moduł ASP.NET Core (ANCM) nie był wybranym składnikiem po zainstalowaniu Visual Studio lub jeśli poprzednia 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 Pakiet hostingu.