Co nowego w programie ASP.NET Core na platformie .NET 7

W tym artykule przedstawiono najważniejsze zmiany w programie ASP.NET Core na platformie .NET 7 z linkami do odpowiedniej dokumentacji.

Ograniczanie szybkości oprogramowania pośredniczącego w programie ASP.NET Core

Oprogramowanie Microsoft.AspNetCore.RateLimiting pośredniczące zapewnia ograniczanie szybkości. Aplikacje konfigurują zasady ograniczania szybkości, a następnie dołączają zasady do punktów końcowych. Aby uzyskać więcej informacji, zobacz Ograniczanie szybkości oprogramowania pośredniczącego w programie ASP.NET Core.

Uwierzytelnianie używa pojedynczego schematu jako domyślnego schematu

W ramach pracy w celu uproszczenia uwierzytelniania, jeśli jest zarejestrowany tylko jeden schemat uwierzytelniania, jest on automatycznie używany jako DefaultScheme element i nie musi być określony. Aby uzyskać więcej informacji, zobacz DefaultScheme.

MVC i Razor strony

Obsługa modeli o wartości null w widokach MVC i stronach Razor

Modele stron lub widoków zezwalające na wartości null są obsługiwane w celu poprawy doświadczenia podczas korzystania ze sprawdzania stanu wartości null w aplikacjach platformy ASP.NET Core.

@model Product?

Wiązanie z IParsable<T>.TryParse w kontrolerach MVC i interfejsu API

Interfejs IParsable<TSelf>.TryParse API obsługuje wiązanie wartości parametrów akcji kontrolera. Aby uzyskać więcej informacji, zobacz Wiązanie z IParsable<T>.TryParse.

W wersjach ASP.NET Core wcześniejszych niż 7 cookie weryfikacja zgody używa cookie wartości yes w celu wskazania zgody. Teraz możesz określić wartość reprezentującą zgodę. Można na przykład użyć polecenia true zamiast yes:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.Configure<CookiePolicyOptions>(options =>
{
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
    options.ConsentCookieValue = "true";
});

var app = builder.Build();

Aby uzyskać więcej informacji, zobacz Dostosowywanie cookie wartości zgody.

Kontrolery interfejsu API

Powiązanie parametrów za pomocą DI w kontrolerach API

Powiązanie parametrów dla akcji kontrolera interfejsu API wiąże parametry za pośrednictwem wstrzykiwania zależności, gdy typ jest skonfigurowany jako usługa. Oznacza to, że nie jest już wymagane jawne zastosowanie atrybutu [FromServices] do parametru. W poniższym kodzie obie akcje zwracają czas:

[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{
    public ActionResult GetWithAttribute([FromServices] IDateTime dateTime) 
                                                        => Ok(dateTime.Now);

    [Route("noAttribute")]
    public ActionResult Get(IDateTime dateTime) => Ok(dateTime.Now);
}

W rzadkich przypadkach automatyczne DI może spowodować awarię aplikacji, które mają typ w DI, który jest również akceptowany w metodzie akcji kontrolerów API. Typ w DI i jako argument w akcji kontrolera API to nie są często spotykane. Aby wyłączyć automatyczne powiązanie parametrów, ustaw wartość DisableImplicitFromServicesParameters

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddSingleton<IDateTime, SystemDateTime>();

builder.Services.Configure<ApiBehaviorOptions>(options =>
{
    options.DisableImplicitFromServicesParameters = true;
});

var app = builder.Build();

app.MapControllers();

app.Run();

Na platformie .NET 7 typy w DI są sprawdzane podczas uruchamiania aplikacji z IServiceProviderIsService, aby określić, czy argument w akcji kontrolera interfejsu API pochodzi z DI czy z innych źródeł.

Nowy mechanizm wnioskowania źródła powiązania parametrów akcji kontrolera interfejsu API używa następujących reguł:

  1. Wcześniej określony BindingInfo.BindingSource element nigdy nie został zastąpiony.
  2. Przypisano BindingSource.Services do zarejestrowanego w kontenerze DI parametru typu złożonego.
  3. Przypisano BindingSource.Bodyparametr typu złożonego, który nie został zarejestrowany w kontenerze DI.
  4. Parametr o nazwie, która jest wyświetlana jako wartość trasy w dowolnym szablonie trasy, jest przypisany BindingSource.Path.
  5. Wszystkie inne parametry to BindingSource.Query.

Nazwy właściwości JSON w błędach walidacji

Domyślnie, gdy wystąpi błąd weryfikacji, walidacja modelu generuje ModelStateDictionary z nazwą właściwości jako klucz błędu. Niektóre aplikacje, takie jak aplikacje jednostronicowe, korzystają z używania nazw właściwości JSON na potrzeby błędów walidacji generowanych przez internetowe interfejsy API. Poniższy kod konfiguruje walidację, aby używać SystemTextJsonValidationMetadataProvider do korzystania z nazw właściwości JSON.

using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    options.ModelMetadataDetailsProviders.Add(new SystemTextJsonValidationMetadataProvider());
});

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Poniższy kod konfiguruje walidację tak, aby używała NewtonsoftJsonValidationMetadataProvider nazwy właściwości JSON w przypadku używania Json.NET:

using Microsoft.AspNetCore.Mvc.NewtonsoftJson;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    options.ModelMetadataDetailsProviders.Add(new NewtonsoftJsonValidationMetadataProvider());
}).AddNewtonsoftJson();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Aby uzyskać więcej informacji, zobacz Use JSON property names in validation errors (Używanie nazw właściwości JSON w błędach walidacji)

Minimalne API

Filtry w aplikacjach Minimal API

Minimalne filtry interfejsu API umożliwiają deweloperom implementowanie logiki biznesowej, która obsługuje:

  • Uruchamianie kodu przed i po procedurze obsługi tras.
  • Sprawdzanie i modyfikowanie parametrów podanych podczas wywołania procedury obsługi tras.
  • Przechwytywanie zachowania odpowiedzi programu obsługi tras.

Filtry mogą być przydatne w następujących scenariuszach:

  • Weryfikowanie parametrów żądania i treści wysyłanych do punktu końcowego.
  • Rejestrowanie informacji o żądaniu i odpowiedzi.
  • Weryfikowanie, czy żądanie dotyczy obsługiwanej wersji interfejsu API.

Aby uzyskać więcej informacji, zobacz Filtry w minimalnych aplikacjach interfejsu API

Powiąż tablice i wartości tekstowe z nagłówków oraz ciągów w zapytaniach

W ASP.NET 7 obsługiwane jest powiązanie ciągów zapytania z tablicą typów pierwotnych, tablic ciągów i StringValues.

// Bind query string values to a primitive type array.
// GET  /tags?q=1&q=2&q=3
app.MapGet("/tags", (int[] q) =>
                      $"tag1: {q[0]} , tag2: {q[1]}, tag3: {q[2]}");

// Bind to a string array.
// GET /tags2?names=john&names=jack&names=jane
app.MapGet("/tags2", (string[] names) =>
            $"tag1: {names[0]} , tag2: {names[1]}, tag3: {names[2]}");

// Bind to StringValues.
// GET /tags3?names=john&names=jack&names=jane
app.MapGet("/tags3", (StringValues names) =>
            $"tag1: {names[0]} , tag2: {names[1]}, tag3: {names[2]}");

Powiązanie ciągów zapytania lub wartości nagłówków z tablicą typów złożonych jest obsługiwane, gdy typ ma zaimplementowany `TryParse`. Aby uzyskać więcej informacji, zobacz Wiązanie tablic i wartości ciągów z nagłówków i ciągów zapytania.

Aby uzyskać więcej informacji, zobacz Dodawanie podsumowania lub opisu punktu końcowego.

Powiąż treść żądania jako element Stream lub PipeReader

Treść żądania może być powiązana jako Stream lub PipeReader, aby efektywnie wspierać scenariusze, w których użytkownik musi przetwarzać dane i:

  • Zapisz dane w magazynie obiektów blob lub umieść dane w kolejce.
  • Przetwarzanie przechowywanych danych za pomocą procesu roboczego lub funkcji w chmurze.

Na przykład dane mogą być w kolejce do usługi Azure Queue Storage lub przechowywane w usłudze Azure Blob Storage.

Aby uzyskać więcej informacji, zobacz Wiązanie treści żądania jako elementu Stream lub PipeReader

Nowe przeciążenia Results.Stream

Wprowadziliśmy nowe przeciążenia Results.Stream umożliwiające dostęp do bazowego strumienia odpowiedzi HTTP bez buforowania w określonych scenariuszach. Te przeciążenia zwiększają również sytuacje, w których API przesyła strumieniowo dane do strumienia odpowiedzi HTTP, na przykład z usługi Azure Blob Storage. W poniższym przykładzie użyto elementu ImageSharp w celu zwrócenia mniejszego rozmiaru określonego obrazu:

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/process-image/{strImage}", (string strImage, HttpContext http, CancellationToken token) =>
{
    http.Response.Headers.CacheControl = $"public,max-age={TimeSpan.FromHours(24).TotalSeconds}";
    return Results.Stream(stream => ResizeImageAsync(strImage, stream, token), "image/jpeg");
});

async Task ResizeImageAsync(string strImage, Stream stream, CancellationToken token)
{
    var strPath = $"wwwroot/img/{strImage}";
    using var image = await Image.LoadAsync(strPath, token);
    int width = image.Width / 2;
    int height = image.Height / 2;
    image.Mutate(x =>x.Resize(width, height));
    await image.SaveAsync(stream, JpegFormat.Instance, cancellationToken: token);
}

Aby uzyskać więcej informacji, zobacz Przykłady usługi Stream

Wpisane wyniki dla minimalnych interfejsów API

W programie .NET 6 IResult interfejs został wprowadzony do reprezentowania wartości zwracanych z minimalnych interfejsów API, które nie korzystają z niejawnej obsługi formatu JSON serializującego zwrócony obiekt do odpowiedzi HTTP. Statyczna klasa Results służy do tworzenia różnych IResult obiektów reprezentujących różne typy odpowiedzi. Na przykład ustawienie kodu stanu odpowiedzi lub przekierowanie do innego adresu URL. Typy struktur implementowanych przez IResult, które są zwracane z tych metod, były jednak wewnętrzne, co utrudnia sprawdzenie, czy określony IResult typ jest zwracany z metod w teście jednostkowym.

Na platformie .NET 7 typy implementujące IResult są publiczne, co umożliwia asercji typów podczas testowania. Przykład:

[TestClass()]
public class WeatherApiTests
{
    [TestMethod()]
    public void MapWeatherApiTest()
    {
        var result = WeatherApi.GetAllWeathers();
        Assert.IsInstanceOfType(result, typeof(Ok<WeatherForecast[]>));
    }      
}

Ulepszona możliwość testowania jednostkowego dla minimalnych procedur obsługi tras

IResult Typy implementacji są teraz dostępne publicznie w przestrzeni nazw Microsoft.AspNetCore.Http.HttpResults. Typy IResult implementacji mogą służyć do testów jednostkowych minimalnych procedur obsługi tras, podczas używania nazwanych metod zamiast lambd.

Poniższy kod używa Ok<TValue> klasy :

[Fact]
public async Task GetTodoReturnsTodoFromDatabase()
{
    // Arrange
    await using var context = new MockDb().CreateDbContext();

    context.Todos.Add(new Todo
    {
        Id = 1,
        Title = "Test title",
        Description = "Test description",
        IsDone = false
    });

    await context.SaveChangesAsync();

    // Act
    var result = await TodoEndpointsV1.GetTodo(1, context);

    //Assert
    Assert.IsType<Results<Ok<Todo>, NotFound>>(result);

    var okResult = (Ok<Todo>)result.Result;

    Assert.NotNull(okResult.Value);
    Assert.Equal(1, okResult.Value.Id);
}

Aby uzyskać więcej informacji, zobacz IResult typy implementacji.

Nowe interfejsy HttpResult

Następujące interfejsy w Microsoft.AspNetCore.Http przestrzeni nazw umożliwiają wykrywanie IResult typu w czasie wykonywania, co jest typowym wzorcem w implementacjach filtrów.

Aby uzyskać więcej informacji, zobacz interfejsy IHttpResult.

Ulepszenia OpenAPI dla minimalistycznych API

Microsoft.AspNetCore.OpenApi Pakiet NuGet

Pakiet Microsoft.AspNetCore.OpenApi umożliwia interakcje ze specyfikacjami interfejsu OpenAPI dla punktów końcowych. Pakiet działa jako link między modelami OpenAPI zdefiniowanymi w pakiecie Microsoft.AspNetCore.OpenApi a punktami końcowymi zdefiniowanymi w minimalnych interfejsach API. Pakiet udostępnia interfejs API, który analizuje parametry, odpowiedzi i metadane punktu końcowego w celu konstruowania typu adnotacji interfejsu OpenAPI używanego do opisywania punktu końcowego.

app.MapPost("/todoitems/{id}", async (int id, Todo todo, TodoDb db) =>
{
    todo.Id = id;
    db.Todos.Add(todo);
    await db.SaveChangesAsync();

    return Results.Created($"/todoitems/{todo.Id}", todo);
})
.WithOpenApi();

Wywołaj WithOpenApi z parametrami

Metoda WithOpenApi akceptuje funkcję, która może służyć do modyfikowania adnotacji interfejsu OpenAPI. Na przykład w poniższym kodzie opis jest dodawany do pierwszego parametru punktu końcowego:

app.MapPost("/todo2/{id}", async (int id, Todo todo, TodoDb db) =>
{
    todo.Id = id;
    db.Todos.Add(todo);
    await db.SaveChangesAsync();

    return Results.Created($"/todoitems/{todo.Id}", todo);
})
.WithOpenApi(generatedOperation =>
{
    var parameter = generatedOperation.Parameters[0];
    parameter.Description = "The ID associated with the created Todo";
    return generatedOperation;
});

Podaj opisy i podsumowania punktów końcowych

Minimalne interfejsy API obsługują teraz dodawanie adnotacji do operacji, wraz z opisami i podsumowaniami, w celu generowania specyfikacji OpenAPI. Możesz wywołać metody rozszerzeń WithDescription i WithSummary lub użyć atrybutów [EndpointDescription] i [EndpointSummary]).

Aby uzyskać więcej informacji, zobacz OpenAPI w minimalnych aplikacjach interfejsu API

Przekazywanie plików za pomocą elementu IFormFile i IFormFileCollection

Minimalne interfejsy API obsługują teraz przesyłanie plików za pomocą IFormFile i IFormFileCollection. Poniższy kod używa instrukcji IFormFile i IFormFileCollection do przekazywania pliku:

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

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

app.MapPost("/upload", async (IFormFile file) =>
{
    var tempFile = Path.GetTempFileName();
    app.Logger.LogInformation(tempFile);
    using var stream = File.OpenWrite(tempFile);
    await file.CopyToAsync(stream);
});

app.MapPost("/upload_many", async (IFormFileCollection myFiles) =>
{
    foreach (var file in myFiles)
    {
        var tempFile = Path.GetTempFileName();
        app.Logger.LogInformation(tempFile);
        using var stream = File.OpenWrite(tempFile);
        await file.CopyToAsync(stream);
    }
});

app.Run();

Uwierzytelnione żądania przekazywania plików są obsługiwane przy użyciu nagłówka autoryzacji, certyfikatu klienta lub nagłówka cookie .

Brak wbudowanej obsługi ochrony przed fałszerzami. Można go jednak zaimplementować przy użyciu IAntiforgery usługi.

[AsParameters] atrybut umożliwia wiązanie parametrów dla list argumentów

Atrybut [AsParameters] umożliwia powiązanie parametrów dla list argumentów. Aby uzyskać więcej informacji, zobacz Powiązanie parametrów dla list argumentów za pomocą polecenia [AsParameters].

Minimalne interfejsy API i kontrolery interfejsów API

Nowa usługa szczegółów problemu

Usługa szczegółów problemu IProblemDetailsService implementuje interfejs, który obsługuje tworzenie Szczegółów Problemu dla API protokołu HTTP.

Aby uzyskać więcej informacji, zobacz Usługa szczegółów problemu.

Grupy tras

Metoda MapGroup rozszerzenia ułatwia organizowanie grup punktów końcowych za pomocą wspólnego prefiksu i zmniejsza powtarzalny kod. Ta metoda służy do dostosowywania całych grup punktów końcowych za pomocą jednego wywołania metod, takich jak RequireAuthorization i WithMetadata dodawania metadanych punktu końcowego.

Na przykład poniższy kod tworzy dwie podobne grupy punktów końcowych:

app.MapGroup("/public/todos")
    .MapTodosApi()
    .WithTags("Public");

app.MapGroup("/private/todos")
    .MapTodosApi()
    .WithTags("Private")
    .AddEndpointFilterFactory(QueryPrivateTodos)
    .RequireAuthorization();


EndpointFilterDelegate QueryPrivateTodos(EndpointFilterFactoryContext factoryContext, EndpointFilterDelegate next)
{
    var dbContextIndex = -1;

    foreach (var argument in factoryContext.MethodInfo.GetParameters())
    {
        if (argument.ParameterType == typeof(TodoDb))
        {
            dbContextIndex = argument.Position;
            break;
        }
    }

    // Skip filter if the method doesn't have a TodoDb parameter.
    if (dbContextIndex < 0)
    {
        return next;
    }

    return async invocationContext =>
    {
        var dbContext = invocationContext.GetArgument<TodoDb>(dbContextIndex);
        dbContext.IsPrivate = true;

        try
        {
            return await next(invocationContext);
        }
        finally
        {
            // This should only be relevant if you're pooling or otherwise reusing the DbContext instance.
            dbContext.IsPrivate = false;
        }
    };
}
public static RouteGroupBuilder MapTodosApi(this RouteGroupBuilder group)
{
    group.MapGet("/", GetAllTodos);
    group.MapGet("/{id}", GetTodo);
    group.MapPost("/", CreateTodo);
    group.MapPut("/{id}", UpdateTodo);
    group.MapDelete("/{id}", DeleteTodo);

    return group;
}

W tym scenariuszu możesz użyć względnego adresu nagłówka Location w 201 Created wyniku:

public static async Task<Created<Todo>> CreateTodo(Todo todo, TodoDb database)
{
    await database.AddAsync(todo);
    await database.SaveChangesAsync();

    return TypedResults.Created($"{todo.Id}", todo);
}

Pierwsza grupa punktów końcowych odpowiada tylko żądaniom poprzedzonym prefiksem /public/todos i jest dostępna bez żadnego uwierzytelniania. Druga grupa punktów końcowych odpowiada tylko żądaniom poprzedzonym prefiksem /private/todos i wymaga uwierzytelniania.

QueryPrivateTodos to funkcja lokalna, która modyfikuje TodoDb parametry programu obsługi tras, aby umożliwić im dostęp do prywatnych danych zadań do wykonania i przechowywanie ich. QueryPrivateTodos służy jako fabryka filtrów punktów końcowych.

Grupy tras obsługują również zagnieżdżone grupy oraz złożone wzorce prefiksów z parametrami i ograniczeniami dla tras. W poniższym przykładzie obsługiwacz tras zamapowany na grupę user może przechwytywać parametry trasy {org} i {group} zdefiniowane w prefiksach grup zewnętrznych.

Prefiks może być również pusty. Takie podejście może być przydatne w przypadku dodawania metadanych lub filtrów punktu końcowego do grupy punktów końcowych bez zmiany wzorca trasy.

var all = app.MapGroup("").WithOpenApi();
var org = all.MapGroup("{org}");
var user = org.MapGroup("{user}");
user.MapGet("", (string org, string user) => $"{org}/{user}");

Dodanie filtrów lub metadanych do grupy powoduje takie samo zachowanie, jak dodawanie ich indywidualnie do każdego punktu końcowego (przed dodaniem dodatkowych filtrów lub metadanych, które mogą istnieć w grupie wewnętrznej lub określonym punkcie końcowym).

var outer = app.MapGroup("/outer");
var inner = outer.MapGroup("/inner");

inner.AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("/inner group filter");
    return next(context);
});

outer.AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("/outer group filter");
    return next(context);
});

inner.MapGet("/", () => "Hi!").AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("MapGet filter");
    return next(context);
});

W poprzednim przykładzie zewnętrzny filtr rejestruje przychodzące żądanie przed filtrem wewnętrznym, mimo że filtr zewnętrzny jest dodawany jako drugi. Ponieważ filtry są stosowane do różnych grup, kolejność ich dodawania względem siebie nie ma znaczenia. Kolejność dodawania filtrów ma znaczenie w przypadku zastosowania do tej samej grupy lub określonego punktu końcowego.

Żądanie do /outer/inner/ rejestruje następujące dane:

/outer group filter
/inner group filter
MapGet filter

gRPC

Transkodowanie JSON

Transkodowanie gRPC JSON to rozszerzenie dla ASP.NET Core, które tworzy interfejsy API RESTful JSON dla usług gRPC. Transkodowanie gRPC JSON umożliwia:

  • Aplikacje do wywoływania usług gRPC w oparciu o znane koncepcje HTTP.
  • ASP.NET Core aplikacje gRPC, które obsługują zarówno interfejsy API gRPC, jak i RESTful JSON, bez replikowania funkcjonalności.
  • Eksperymentalna obsługa generowania interfejsu OpenAPI z transkodowanych interfejsów API RESTful przez integrację z pakietem Swashbuckle.

Aby uzyskać więcej informacji, zobacz transkodowanie gRPC JSON w aplikacjach gRPC platformy ASP.NET Core.

kontrole kondycji gRPC w programie ASP.NET Core

Protokół kontroli kondycji gRPC jest standardem raportowania kondycji aplikacji serwera gRPC. Aplikacja udostępnia testy kondycji jako usługę gRPC. Są one zwykle używane z zewnętrzną usługą monitorowania w celu sprawdzenia stanu aplikacji.

gRPC ASP.NET Core dodał wbudowaną obsługę monitorowania kondycji gRPC z pakietem Grpc.AspNetCore.HealthChecks. Wyniki kontroli stanu zdrowia platformy .NET są zgłaszane do osób wywołujących.

Aby uzyskać więcej informacji, zobacz kontrole kondycji gRPC w ASP.NET Core.

Ulepszona obsługa poświadczeń połączeń

Dane uwierzytelniające wywołania są zalecanym sposobem konfigurowania klienta gRPC do wysyłania tokenu uwierzytelniającego do serwera. Klienty gRPC obsługują dwie nowe funkcje, umożliwiające łatwiejsze używanie poświadczeń wywołania.

  • Obsługa poświadczeń wywołania z niezaszyfrowanymi połączeniami. Wcześniej wywołanie gRPC wysyłało poświadczenia wywołania tylko wtedy, gdy połączenie zostało zabezpieczone przy użyciu protokołu TLS. Nowe ustawienie w systemie GrpcChannelOptionso nazwie UnsafeUseInsecureChannelCallCredentialsumożliwia dostosowanie tego zachowania. Istnieją konsekwencje bezpieczeństwa w przypadku braku zabezpieczenia połączenia protokołem TLS.
  • Nowa metoda o nazwie AddCallCredentials jest dostępna w fabryce klienta gRPC. AddCallCredentials to szybki sposób konfigurowania poświadczeń dla klienta gRPC i dobrze integruje się ze wstrzykiwaniem zależności (DI).

Poniższy kod konfiguruje fabrykę klienta gRPC w celu wysyłania Authorization metadanych:

builder.Services
    .AddGrpcClient<Greeter.GreeterClient>(o =>
    {
       o.Address = new Uri("https://localhost:5001");
    })
    .AddCallCredentials((context, metadata) =>
    {
       if (!string.IsNullOrEmpty(_token))
       {
          metadata.Add("Authorization", $"Bearer {_token}");
       }
       return Task.CompletedTask;
    });

Aby uzyskać więcej informacji, zobacz Konfigurowanie tokenu nosiciela za pomocą fabryki klienta gRPC.

SignalR

Wyniki klienta

Serwer obsługuje teraz żądanie wyniku od klienta. Wymaga to, aby serwer używał ISingleClientProxy.InvokeAsync, a klient zwrócił wynik z procedury .On obsługi. Silnie typizowane koncentratory mogą również zwracać wartości z metod interfejsu.

Aby uzyskać więcej informacji, zobacz Wyniki klienta

Wstrzykiwanie zależności dla SignalR metod koncentratora

SignalR metody koncentratora obsługują teraz wstrzykiwanie usług za pomocą wstrzykiwania zależności (DI).

Konstruktory koncentratorów mogą akceptować usługi z DI jako parametry, które można przechowywać we właściwościach klasy, aby następnie użyć ich w metodzie koncentratora. Aby uzyskać więcej informacji, zobacz temat Wstrzykiwanie usług do huba.

Blazor

Obsługa zdarzeń zmiany lokalizacji i stanu nawigacji

Na platformie .NET 7 Blazor obsługuje zdarzenia zmiany położenia i zarządzanie stanem nawigacji. Dzięki temu można ostrzegać użytkowników o niezapisanej pracy lub wykonywać powiązane akcje, gdy użytkownik wykonuje nawigację po stronie.

Aby uzyskać więcej informacji, zobacz następujące sekcje artykułu Routing i nawigacja :

Puste Blazor szablony projektów

Blazor ma dwa nowe szablony projektów do rozpoczęcia od zera. Nowe Blazor Server szablony projektów Aplikacje puste i Blazor WebAssembly Puste aplikacje są podobne do ich niepustych odpowiedników, ale bez przykładowego kodu. Te puste szablony obejmują tylko podstawową stronę główną i usunęliśmy metodę Bootstrap, aby rozpocząć pracę z inną strukturą CSS.

Aby uzyskać więcej informacji, zobacz następujące artykuły:

Niestandardowe elementy Blazor

Pakiet Microsoft.AspNetCore.Components.CustomElements umożliwia tworzenie niestandardowych elementów DOM opartych na standardach przy użyciu polecenia Blazor.

Aby uzyskać więcej informacji, zobacz ASP.NET Core Razor komponenty.

Modyfikatory powiązań (@bind:after, @bind:get, @bind:set)

Important

W tej chwili, funkcje @bind:after/@bind:get/@bind:set są aktualizowane. Aby skorzystać z najnowszych aktualizacji, upewnij się, że zainstalowano najnowszy zestaw SDK.

Używanie parametru wywołania zwrotnego zdarzeń ([Parameter] public EventCallback<string> ValueChanged { get; set; }) nie jest obsługiwane. Zamiast tego przekaż metodę zwracającą Action lub Task do @bind:set/@bind:after.

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

Na platformie .NET 7 można uruchomić logikę asynchroniczną po zakończeniu zdarzenia powiązania przy użyciu nowego @bind:after modyfikatora. W poniższym przykładzie PerformSearch metoda asynchroniczna jest uruchamiana automatycznie po wykryciu wszelkich zmian w tekście wyszukiwania:

<input @bind="searchText" @bind:after="PerformSearch" />

@code {
    private string searchText;

    private async Task PerformSearch()
    {
        ...
    }
}

W programie .NET 7 łatwiej jest również skonfigurować powiązanie parametrów składnika. Składniki mogą obsługiwać dwukierunkowe powiązanie danych, definiując parę parametrów:

  • @bind:get: określa wartość, która ma być powiązana.
  • @bind:set: określa wywołanie zwrotne dla momentu zmiany wartości.

Modyfikatory @bind:get i @bind:set są zawsze używane razem.

Examples:

@* Elements *@

<input type="text" @bind="text" @bind:after="() => { }" />

<input type="text" @bind:get="text" @bind:set="(value) => { }" />

<input type="text" @bind="text" @bind:after="AfterAsync" />

<input type="text" @bind:get="text" @bind:set="SetAsync" />

<input type="text" @bind="text" @bind:after="() => { }" />

<input type="text" @bind:get="text" @bind:set="(value) => { }" />

<input type="text" @bind="text" @bind:after="AfterAsync" />

<input type="text" @bind:get="text" @bind:set="SetAsync" />

@* Components *@

<InputText @bind-Value="text" @bind-Value:after="() => { }" />

<InputText @bind-Value:get="text" @bind-Value:set="(value) => { }" />

<InputText @bind-Value="text" @bind-Value:after="AfterAsync" />

<InputText @bind-Value:get="text" @bind-Value:set="SetAsync" />

<InputText @bind-Value="text" @bind-Value:after="() => { }" />

<InputText @bind-Value:get="text" @bind-Value:set="(value) => { }" />

<InputText @bind-Value="text" @bind-Value:after="AfterAsync" />

<InputText @bind-Value:get="text" @bind-Value:set="SetAsync" />

@code {
    private string text = "";

    private void After(){}
    private void Set() {}
    private Task AfterAsync() { return Task.CompletedTask; }
    private Task SetAsync(string value) { return Task.CompletedTask; }
}

Aby uzyskać więcej informacji na temat składnika InputText, zobacz ASP.NET Core Blazor składniki wejściowe.

Ulepszenia funkcji Przeładowywanie na gorąco

W programie .NET 7 obsługa Przeładowywanie na gorąco obejmuje następujące elementy:

  • Składniki resetują swoje parametry do wartości domyślnych po usunięciu wartości.
  • Blazor WebAssembly:
    • Dodaj nowe typy.
    • Dodaj zagnieżdżone klasy.
    • Dodawanie metod statycznych i wystąpień do istniejących typów.
    • Dodaj pola statyczne i metody do istniejących typów.
    • Dodaj statyczne lambdy do istniejących metod.
    • Dodaj lambdy, które przechwytują this, do istniejących metod, które wcześniej przechwytywały this.

Żądania dynamicznego uwierzytelniania za pomocą Microsoft Authentication Library (MSAL) w Blazor WebAssembly

Nowości w .NET 7, Blazor WebAssembly wspiera tworzenie dynamicznych żądań uwierzytelniania w czasie wykonywania z niestandardowymi parametrami, aby obsłużyć zaawansowane scenariusze uwierzytelniania.

Aby uzyskać więcej informacji, zobacz następujące artykuły:

Blazor WebAssembly ulepszenia debugowania

Blazor WebAssembly Debugowanie ma następujące ulepszenia:

  • Obsługa ustawienia Tylko mój kod w celu wyświetlania lub ukrywania elementów członkowskich typu, które nie pochodzą z kodu użytkownika.
  • Obsługa inspekcji tablic wielowymiarowych.
  • Stos wywołań pokazuje teraz poprawną nazwę metod asynchronicznych.
  • Ulepszona ocena wyrażeń.
  • Poprawna obsługa słowa kluczowego new dla pochodnych elementów członkowskich.
  • Obsługa atrybutów związanych z debugerem w programie System.Diagnostics.

System.Security.Cryptography obsługa zestawu WebAssembly

.NET 6 obsługiwała rodzinę algorytmów haszujących SHA podczas uruchamiania w środowisku WebAssembly. Platforma .NET 7 umożliwia korzystanie z większej liczby algorytmów kryptograficznych, wykorzystując SubtleCrypto, jeśli jest to możliwe, oraz powrót do implementacji platformy .NET, gdy SubtleCrypto nie może być wykorzystane. Następujące algorytmy są obsługiwane przez WebAssembly w .NET 7:

  • SHA1
  • SHA256
  • SHA384
  • SHA512
  • HMACSHA1
  • HMACSHA256
  • HMACSHA384
  • HMACSHA512
  • AES-CBC
  • PBKDF2
  • HKDF

Aby uzyskać więcej informacji, zobacz Deweloperzy celujący w browser-wasm mogą używać Web Crypto APIs (dotnet/runtime #40074).

Wstrzykiwanie usług do niestandardowych atrybutów walidacji

Teraz możesz wstrzyknąć usługi do niestandardowych atrybutów walidacji. Blazor Konfiguruje element ValidationContext tak, aby mógł być używany jako dostawca usług.

Aby uzyskać więcej informacji, zobacz walidację formularzy Blazor ASP.NET Core.

Input* komponenty poza elementem EditContext/EditForm

Wbudowane komponenty wejściowe są teraz obsługiwane poza formularzem w składni komponentu Razor.

Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor komponenty wejściowe.

Zmiany szablonu projektu

Gdy .NET 6 został wydany w zeszłym roku, znaczniki HTML strony _Host (Pages/_Host.chstml) zostały podzielone między stronę _Host a nową stronę _Layout (Pages/_Layout.chstml) w szablonie projektu .NET 6 Blazor Server.

Na platformie .NET 7, znaczniki HTML zostały ponownie połączone ze stroną _Host w szablonach projektów.

Wprowadzono kilka dodatkowych zmian w szablonach Blazor projektów. Nie jest możliwe wyświetlenie listy wszystkich zmian w szablonach w dokumentacji. Aby przeprowadzić migrację aplikacji do platformy .NET 7 w celu wdrożenia wszystkich zmian, zobacz Migrowanie z platformy ASP.NET Core na platformie .NET 6 do platformy .NET 7.

Składnik eksperymentalny QuickGrid

Nowy QuickGrid składnik udostępnia wygodny składnik siatki danych dla najbardziej typowych wymagań oraz jako architekturę referencyjną i punkt odniesienia wydajności dla każdego, kto tworzy Blazor składniki siatki danych.

Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor "QuickGrid" składnik.

Pokaz na żywo: QuickGrid dla przykładowej aplikacji Blazor

Ulepszenia wirtualizacji

Ulepszenia wirtualizacji na platformie .NET 7:

  • Składnik Virtualize obsługuje wykorzystanie samego dokumentu jako korzenia przewijania, jako alternatywę dla zastosowania overflow-y: scroll do innego elementu.
  • Virtualize Jeśli składnik zostanie umieszczony wewnątrz elementu, który wymaga określonej nazwy tagu podrzędnego, SpacerElement umożliwia uzyskanie lub ustawienie nazwy tagu spacer wirtualizacji.

Aby uzyskać więcej informacji, zobacz następujące sekcje artykułu Wirtualizacja :

MouseEventArgs Aktualizacje

MovementX i MovementY zostały dodane do elementu MouseEventArgs.

Aby uzyskać więcej informacji, zobacz obsługę zdarzeń ASP.NET Core.

Nowy Blazor ekran ładowania

Szablon Blazor WebAssembly projektu ma nowy interfejs ładowania, który pokazuje postęp ładowania aplikacji.

Aby uzyskać więcej informacji, zobacz uruchamianie ASP.NET CoreBlazor.

Ulepszona diagnostyka uwierzytelniania w programie Blazor WebAssembly

Aby ułatwić diagnozowanie problemów z uwierzytelnianiem w Blazor WebAssembly aplikacjach, dostępne jest szczegółowe rejestrowanie.

Aby uzyskać więcej informacji, zobacz ASP.NET CoreBlazor rejestrowanie.

Współdziałanie JavaScript z WebAssembly

Interfejs API międzyoperacyjny JavaScript [JSImport]/[JSExport] to nowy mechanizm niskiego poziomu umożliwiający używanie platformy .NET w aplikacjach bazujących na JavaScript. Dzięki tej nowej funkcji współpracy z językiem JavaScript można wywoływać kod platformy .NET za pomocą języka JavaScript, używając środowiska uruchomieniowego WebAssembly platformy .NET, oraz wywoływać funkcjonalność JavaScript z platformy .NET bez żadnej zależności od modelu składników interfejsu użytkownika Blazor.

Więcej informacji:

Rejestracja warunkowa dostawcy stanu uwierzytelniania

Przed wydaniem programu .NET 7 AuthenticationStateProvider został zarejestrowany w kontenerze usługi za pomocą polecenia AddScoped. Utrudniało to debugowanie aplikacji, ponieważ wymuszało określoną kolejność rejestracji usług podczas udostępniania niestandardowej implementacji. Ze względu na zmiany w wewnętrznym frameworku z upływem czasu nie jest już konieczne rejestrowanie AuthenticationStateProvider w AddScoped.

W kodzie dewelopera wprowadź następującą zmianę w rejestracji usługi dostawcy stanu uwierzytelniania:

- builder.Services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
+ builder.Services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();

W poprzednim przykładzie ExternalAuthStateProvider jest implementacja usługi dewelopera.

Ulepszenia narzędzi kompilacji zestawu WebAssembly platformy .NET

Nowe funkcje w obciążeniu wasm-tools dla platformy .NET 7, które pomagają zwiększyć wydajność i obsługiwać wyjątki:

Aby uzyskać więcej informacji, zobacz Blazor WebAssembly.

Blazor Hybrid

Zewnętrzne adresy URL

Dodano opcję zezwalającą na otwieranie zewnętrznych stron internetowych w przeglądarce.

Aby uzyskać więcej informacji, zobacz Blazor Hybrid.

Zabezpieczenia

Nowe wskazówki są dostępne dla Blazor Hybrid scenariuszy zabezpieczeń. Aby uzyskać więcej informacji, zobacz następujące artykuły:

Performance

Buforowanie danych wyjściowych w middleware

Buforowanie wyjściowe to nowa warstwa pośrednicząca, która przechowuje odpowiedzi z aplikacji internetowej i serwuje je z pamięci podręcznej, zamiast generować je za każdym razem. Buforowanie danych wyjściowych różni się od buforowania odpowiedzi na następujące sposoby:

  • Zachowanie buforowania można skonfigurować na serwerze.
  • Wpisy pamięci podręcznej można programowo unieważnić.
  • Blokowanie zasobów zmniejsza ryzyko stemplowania pamięci podręcznej i grzmiące stada.
  • Ponowna walidacja pamięci podręcznej oznacza, że serwer może zwrócić 304 Not Modified kod stanu HTTP zamiast treści odpowiedzi pamięci podręcznej.
  • Nośnik pamięci podręcznej jest rozszerzalny.

Aby uzyskać więcej informacji, zobacz Omówienie buforowania i oprogramowania pośredniczącego buforowania danych wyjściowych.

Ulepszenia http/3

Ta wersja:

  • Sprawia, że protokół HTTP/3 jest w pełni obsługiwany przez platformę ASP.NET Core, nie jest już eksperymentalny.
  • KestrelPoprawia obsługę protokołu HTTP/3. Dwa główne obszary ulepszania to równoważność funkcji z protokołami HTTP/1.1 i HTTP/2 oraz wydajnością.
  • Zapewnia pełną obsługę protokołu UseHttps(ListenOptions, X509Certificate2) HTTP/3. KestrelOferuje zaawansowane opcje konfigurowania certyfikatów połączeń, takie jak integracja z Server Name Indication (SNI).
  • Dodaje obsługę protokołu HTTP/3 w usługach HTTP.sys i IIS.

W poniższym przykładzie pokazano, jak używać wywołania zwrotnego SNI do rozwiązywania problemów z opcjami protokołu TLS:

using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenAnyIP(8080, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
        listenOptions.UseHttps(new TlsHandshakeCallbackOptions
        {
            OnConnection = context =>
            {
                var options = new SslServerAuthenticationOptions
                {
                    ServerCertificate = 
                         MyResolveCertForHost(context.ClientHelloInfo.ServerName)
                };
                return new ValueTask<SslServerAuthenticationOptions>(options);
            },
        });
    });
});

Znaczna praca została wykonana na platformie .NET 7 w celu zmniejszenia alokacji HTTP/3. Niektóre z tych ulepszeń można zobaczyć w następujących żądaniach pull request na GitHubie:

Ulepszenia wydajności HTTP/2

Platforma .NET 7 wprowadza znaczącą ponowną architekturę sposobu Kestrel przetwarzania żądań HTTP/2. Aplikacje ASP.NET Core z zajętymi połączeniami HTTP/2 będą doświadczać mniejszego użycia CPU i wyższej przepływności.

Wcześniej implementacja multipleksowania HTTP/2 polegała na blokadzie kontrolującej, które żądanie może być zapisane w bazowym połączeniu TCP. Kolejka bezpieczna wątkowo zastępuje blokadę zapisu. Teraz, zamiast walczyć o to, który wątek ma korzystać z blokady zapisu, żądania są teraz kolejkowane w górę i dedykowany użytkownik przetwarza je. Wcześniej zmarnowane zasoby CPU są teraz dostępne dla reszty aplikacji.

Jednym z miejsc, w których można zauważyć te ulepszenia, jest gRPC, popularna struktura RPC korzystająca z protokołu HTTP/2. Kestrel + testy porównawcze gRPC pokazują dramatyczną poprawę:

Wydajność przesyłania strumieniowego serwera gRPC

Zmiany zostały wprowadzone w kodzie pisania ramek HTTP/2, co poprawia wydajność, gdy wiele strumieni próbuje zapisać dane na jednej sesji HTTP/2. Teraz wysyłamy pracę protokołu TLS do puli wątków i szybciej zwalniamy blokadę zapisu, którą inne strumienie mogą uzyskać w celu zapisania danych. Zmniejszenie czasu oczekiwania może przynieść znaczne ulepszenia wydajności w przypadkach, gdy istnieje rywalizacja o tę blokadę zapisu. Test porównawczy gRPC z 70 strumieniami w jednym połączeniu (z protokołem TLS) wykazał około 15% poprawy żądań na sekundę (RPS) z tą zmianą.

Obsługa WebSockets Http/2

Platforma .NET 7 wprowadza obsługę WebSocket przez protokół HTTP/2 dla klienta Kestrel, klienta JavaScript SignalR, oraz SignalR z Blazor WebAssembly.

Korzystanie z WebSocketów w przypadku protokołu HTTP/2, dzięki czemu wykorzystuje nowe funkcje, takie jak:

  • Kompresja nagłówka.
  • Multipleksowanie, co skraca czas i zasoby potrzebne podczas podejmowania wielu żądań na serwerze.

Te obsługiwane funkcje są dostępne na Kestrel wszystkich platformach z obsługą protokołu HTTP/2. Negocjowanie wersji jest automatyczne w przeglądarkach i Kestrel, więc nie są potrzebne żadne nowe interfejsy API.

Aby uzyskać więcej informacji, zobacz Obsługa HTTP/2 WebSocket.

Kestrel ulepszenia wydajności na maszynach o dużej liczbie rdzeni

Kestrel używa ConcurrentQueue<T> do wielu celów. Jednym z celów jest planowanie operacji we/wy w Kestrel domyślnym transporcie gniazd. Partycjonowanie ConcurrentQueue na podstawie skojarzonego gniazda zmniejsza rywalizację i zwiększa przepływność na maszynach z wieloma rdzeniami procesora CPU.

Profilowanie na komputerach z wieloma rdzeniami na platformie .NET 6 wykazało znaczną konkurencję w jednym z Kestrel innych ConcurrentQueue wystąpień, PinnedMemoryPool które Kestrel używa do buforowania bajtów.

W przypadku platformy .NET 7 Kestrelpula pamięci jest partycjonowana w taki sam sposób, jak w przypadku kolejki we/wy, co prowadzi do znacznie niższej rywalizacji i wyższej przepływności na maszynach z wysokim rdzeniem. Na 80-rdzeniowych maszynach wirtualnych ARM64 obserwujemy ponad 500% poprawę liczby odpowiedzi na sekundę (RPS) w benchmarku TechEmpower typu plaintext. Na 48-rdzeniowych maszynach wirtualnych AMD poprawa wynosi prawie 100% w naszym benchmarku JSON HTTPS.

ServerReady zdarzenie do mierzenia czasu uruchamiania aplikacji

Aplikacje korzystające z EventSource mogą mierzyć czas uruchamiania, aby zrozumieć i zoptymalizować wydajność uruchamiania. Nowe ServerReady zdarzenie w programie Microsoft.AspNetCore.Hosting reprezentuje punkt, w którym serwer jest gotowy do odpowiadania na żądania.

Server

Nowe zdarzenie ServerReady do pomiaru czasu uruchamiania

Zdarzenie ServerReady zostało dodane do pomiaru czasu uruchamiania aplikacji ASP.NET Core.

Note

Linki dokumentacyjne do źródła referencyjnego .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla obecne prace rozwojowe nad nadchodzącą wersją .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi.

IIS

Kopiowanie w tle w usługach IIS

Kopiowanie zestawów aplikacji w tle do ASP.NET Core Module (ANCM) dla IIS może zapewnić lepsze doświadczenie użytkownika końcowego niż zatrzymywanie aplikacji przez wdrożenie pliku wyłączającego aplikację.

Aby uzyskać więcej informacji, zobacz Kopiowanie w tle w usługach IIS.

Miscellaneous

Kestrel ulepszenia pełnego łańcucha certyfikacyjnego

Protokół HttpsConnectionAdapterOptions ma nową właściwość ServerCertificateChain typu X509Certificate2Collection, co ułatwia weryfikowanie łańcuchów certyfikatów, umożliwiając określenie pełnego łańcucha, w tym certyfikatów pośrednich. Aby uzyskać więcej informacji, zobacz dotnet/aspnetcore#21513 .

dotnet watch

Ulepszone dane wyjściowe konsoli dla zegarka dotnet

Wyjściowe konsoli narzędzia dotnet watch zostało ulepszone, aby lepiej dopasować się do rejestrowania ASP.NET Core i wyróżniać się emotikonami😮😍.

Oto przykład tego, jak wyglądają nowe dane wyjściowe:

dane wyjściowe dla dotnet watch

Aby uzyskać więcej informacji, zobacz ten pull request na GitHubie.

Konfigurowanie funkcji dotnet watch w celu zawsze ponownego uruchamiania w przypadku niegrzecznych edycji

Niegrzeczne edycje to edycje, których nie można ponownie załadować. Aby skonfigurować dotnet watch do zawsze ponownego uruchamiania bez monitu dla 'rude edits', ustaw zmienną środowiskową DOTNET_WATCH_RESTART_ON_RUDE_EDIT na true.

Tryb ciemny strony wyjątku dla deweloperów

Obsługa trybu ciemnego została dodana do strony wyjątków dewelopera, dzięki wkładowi Patricka Westerhoffa. Aby przetestować tryb ciemny w przeglądarce, na stronie narzędzi deweloperskich ustaw tryb na ciemny. Na przykład w przeglądarce Firefox:

Narzędzia F12 tryb ciemny FF

W przeglądarce Chrome:

Narzędzia deweloperskie F12 Chrome — tryb ciemny

Opcja szablonu projektu do używania metody Program.Main zamiast instrukcji najwyższego poziomu

Szablony .NET 7 zawierają opcję, aby nie używać instrukcji najwyższego poziomu i generować metody namespace i Main zadeklarowane w klasie Program.

Korzystając z interfejsu wiersza polecenia .NET, użyj opcji --use-program-main.

dotnet new web --use-program-main

W programie Visual Studio zaznacz nowe pole wyboru Nie używaj instrukcji najwyższego poziomu podczas tworzenia projektu:

checkbox

Zaktualizowano szablony Platformy Angular i React

Szablon projektu Angular został zaktualizowany do platformy Angular 14. Szablon projektu React został zaktualizowany do platformy React 18.2.

Zarządzaj tokenami internetowymi JSON w trakcie tworzenia za pomocą narzędzia dotnet user-jwts

Nowe dotnet user-jwts narzędzie wiersza polecenia może tworzyć lokalne tokeny internetowe JSON (JWTs) specyficzne dla aplikacji i zarządzać nimi. Aby uzyskać więcej informacji, zobacz Manage JSON Web Tokens in development with dotnet user-jwts (Zarządzanie tokenami JSON Web w środowisku developerskim z użyciem dotnet user-jwts).

Obsługa dodatkowych nagłówków żądań w programie W3CLogger

Teraz można określić dodatkowe nagłówki żądań, które mają zostać zarejestrowane podczas korzystania z rejestratora W3C, wywołując AdditionalRequestHeaders() na W3CLoggerOptions.

services.AddW3CLogging(logging =>
{
    logging.AdditionalRequestHeaders.Add("x-forwarded-for");
    logging.AdditionalRequestHeaders.Add("x-client-ssl-protocol");
});

Aby uzyskać więcej informacji, zobacz Opcje W3CLogger.

Poproś o dekompresję

Nowe oprogramowanie pośredniczące do dekompresji żądań:

  • Umożliwia punktom końcowym interfejsu API akceptowanie żądań ze skompresowaną zawartością.
  • Używa nagłówka HTTP do automatycznego identyfikowania Content-Encoding i dekompresowania żądań zawierających skompresowaną zawartość.
  • Eliminuje konieczność pisania kodu do obsługi skompresowanych żądań.

Aby uzyskać więcej informacji, zobacz Middleware do dekompresji żądań.

Zmiany przełomowe

Artykuły w Zmiany powodujące niezgodność na platformie .NET pomagają zidentyfikować zmiany powodujące niezgodność, które mogą być istotne w trakcie uaktualniania aplikacji do nowszej wersji platformy .NET.