Lezen in het Engels

Delen via


Wat is er nieuw in ASP.NET Core 7.0

In dit artikel worden de belangrijkste wijzigingen in ASP.NET Core 7.0 beschreven met koppelingen naar relevante documentatie.

Snelheidsbeperking middleware in ASP.NET Core

De Microsoft.AspNetCore.RateLimiting middleware biedt snelheidsbeperkende middleware. Apps configureren beleidsregels voor snelheidsbeperking en voegen vervolgens het beleid toe aan eindpunten. Zie Rate limiting middleware in ASP.NET Corevoor meer informatie.

Verificatie maakt gebruik van één schema als DefaultScheme

Als onderdeel van het werk om verificatie te vereenvoudigen, wordt het automatisch gebruikt als het DefaultScheme en hoeft niet te worden opgegeven wanneer er slechts één verificatieschema is geregistreerd. Zie DefaultSchemevoor meer informatie.

MVC- en Razor-pagina's

Ondersteuning voor nullable modellen in MVC-weergaven en Razor Pagina's

Nullable pagina- of weergavemodellen worden ondersteund om de ervaring te verbeteren bij het gebruik van null-toestandcontrole met ASP.NET Core-apps.

@model Product?

Verbinden met IParsable<T>.TryParse in MVC- en API-controllers

De IParsable<TSelf>.TryParse-API ondersteunt het binden van parameterwaarden voor controlleracties. Zie Bind met IParsable<T>.TryParsevoor meer informatie.

In ASP.NET Core-versies ouder dan 7 gebruikt de cookie toestemmingsvalidatie de cookie waarde yes om toestemming aan te geven. U kunt nu de waarde opgeven die toestemming vertegenwoordigt. U kunt bijvoorbeeld true gebruiken in plaats van 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();

Zie De cookie toestemmingswaardeaanpassen voor meer informatie.

API-controllers

Parameterbinding met DI in API-controllers

Parameterbinding voor API-controlleracties verbindt parameters via afhankelijkheidsinjectie wanneer het type is geconfigureerd als een service. Dit betekent dat het niet meer nodig is om het kenmerk [FromServices] expliciet toe te passen op een parameter. In de volgende code retourneren beide acties de tijd:

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

In zeldzame gevallen kan automatische DI apps verbreken die een type DI hebben dat ook wordt geaccepteerd in een actiemethode voor API-controllers. Het is niet gebruikelijk om een type in DI te hebben en als argument in een API-controlleractie. Om de automatische binding van parameters uit te schakelen, stelt u DisableImplicitFromServicesParameters in.

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

In ASP.NET Core 7.0 worden typen in DI gecontroleerd bij het opstarten van de app met IServiceProviderIsService om te bepalen of een argument in een API-controlleractie afkomstig is van DI of van de andere bronnen.

Het nieuwe mechanisme voor het afleiden van bindingsbron van actieparameters voor API Controller gebruikt de volgende regels:

  1. Een eerder opgegeven BindingInfo.BindingSource wordt nooit overschreven.
  2. Aan een complexe typeparameter, geregistreerd in de DI-container, wordt BindingSource.Servicestoegewezen.
  3. Aan een complexe typeparameter, die niet is geregistreerd in de DI-container, wordt BindingSource.Bodytoegewezen.
  4. Een parameter met een naam die wordt weergegeven als een routewaarde in elke routesjabloon wordt toegewezen BindingSource.Path.
  5. Alle andere parameters zijn BindingSource.Query.

JSON-eigenschapsnamen in validatiefouten

Wanneer er een validatiefout optreedt, produceert modelvalidatie standaard een ModelStateDictionary met de eigenschapsnaam als foutsleutel. Sommige apps, zoals apps met één pagina, profiteren van het gebruik van JSON-eigenschapsnamen voor validatiefouten die zijn gegenereerd op basis van web-API's. Met de volgende code wordt validatie geconfigureerd voor het gebruik van de SystemTextJsonValidationMetadataProvider voor het gebruik van JSON-eigenschapsnamen:

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

Met de volgende code wordt validatie geconfigureerd om de NewtonsoftJsonValidationMetadataProvider te gebruiken als JSON-eigenschapsnaam bij gebruik van 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();

Zie voor meer informatie JSON-eigenschapsnamen gebruiken in validatiefouten

Minimale API's

Filters in minimale API-apps

Met minimale API-filters kunnen ontwikkelaars bedrijfslogica implementeren die ondersteuning biedt voor:

  • Code voor en na de route-handler uitvoeren.
  • Parameters inspecteren en wijzigen die zijn opgegeven tijdens een aanroep van een route-handler.
  • Het reactiegedrag van een route-handler onderscheppen.

Filters kunnen handig zijn in de volgende scenario's:

  • Valideren van de aanvraagparameters en hoofdtekst die naar een eindpunt worden verzonden.
  • Informatie over de aanvraag en het antwoord vastleggen.
  • Valideren dat een aanvraag gericht is op een ondersteunde API-versie.

Zie Filters in Minimale API-apps voor meer informatie

Matrices en tekenreekswaarden binden vanuit headers en queryreeksen

In ASP.NET 7 wordt het koppelen van queryreeksen aan een matrix van primitieve typen, tekenreeksmatrices en StringValues ondersteund:

// 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]}");

Het binden van querystrings of headerwaarden aan een array van complexe typen wordt ondersteund wanneer het type TryParse is geïmplementeerd. Zie Bind matrices en tekenreekswaarden uit headers en queryreeksenvoor meer informatie.

Zie Eindpuntsamenvatting of beschrijving toevoegenvoor meer informatie.

Verbind de verzoekinhoud als een Stream of PipeReader

De aanvraagtekst kan worden gebonden als een Stream of PipeReader om efficiënt ondersteuning te bieden voor scenario's waarin de gebruiker gegevens moet verwerken en:

  • Sla de gegevens op in Blob Storage of zet de gegevens in een wachtrij bij een wachtrijprovider.
  • De opgeslagen gegevens verwerken met een werkproces of een cloudfunctie.

De gegevens kunnen bijvoorbeeld worden verzonden naar Azure Queue Storage- of worden opgeslagen in Azure Blob Storage-.

Voor meer informatie, zie Bind het aanvraaglichaam als een Stream of PipeReader

Nieuwe resultaten.Stream-overbelasting

Er zijn nieuwe Results.Stream overbelastingen geïntroduceerd voor scenario's die toegang nodig hebben tot de onderliggende HTTP-antwoordstroom zonder buffering. Deze overbelastingen verbeteren ook gevallen waarin een API gegevens naar de HTTP-antwoordstroom streamt, zoals van Azure Blob Storage. In het volgende voorbeeld wordt ImageSharp- gebruikt om een kleinere grootte van de opgegeven afbeelding te retourneren:

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

Zie Stream-voorbeelden voor meer informatie

Getypte resultaten voor minimale API's

In .NET 6 is de IResult-interface geïntroduceerd om waarden weer te geven die worden geretourneerd door minimale API's die niet gebruikmaken van de impliciete ondersteuning voor JSON waarmee het geretourneerde object wordt geserialiseerd naar het HTTP-antwoord. De statische resultaten klasse wordt gebruikt om verschillende IResult objecten te maken die verschillende typen antwoorden vertegenwoordigen. Stel bijvoorbeeld de antwoordstatuscode in of omleiden naar een andere URL. De door IResult geïmplementeerde frameworktypen die door deze methoden zijn geretourneerd, waren echter intern, wat het moeilijk maakt om te verifiëren welk specifiek IResult type wordt geretourneerd door methoden in een unit test.

In .NET 7 zijn de typen die IResult implementeren openbaar, waardoor typeverklaringen kunnen worden gebruikt bij het testen. Bijvoorbeeld:

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

Verbeterde eenheidstestbaarheid voor minimale route-handlers

IResult implementatietypen zijn nu openbaar beschikbaar in de Microsoft.AspNetCore.Http.HttpResults naamruimte. De IResult implementatietypen kunnen worden gebruikt om minimale routehandlers te testen bij het gebruik van benoemde methoden in plaats van lambdas.

De volgende code maakt gebruik van de Ok<TValue>-klasse:

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

Zie IResult implementatietypenvoor meer informatie.

Nieuwe HttpResult-interfaces

De volgende interfaces in de Microsoft.AspNetCore.Http naamruimte bieden een manier om het IResult type tijdens runtime te detecteren. Dit is een algemeen patroon in filter-implementaties:

Zie IHttpResult-interfacesvoor meer informatie.

OpenAPI-verbeteringen voor minimale API's

Microsoft.AspNetCore.OpenApi NuGet-pakket

Met het Microsoft.AspNetCore.OpenApi-pakket kunnen interacties met OpenAPI-specificaties voor eindpunten worden gebruikt. Het pakket fungeert als een koppeling tussen de OpenAPI-modellen die zijn gedefinieerd in het Microsoft.AspNetCore.OpenApi-pakket en de eindpunten die zijn gedefinieerd in minimale API's. Het pakket biedt een API waarmee de parameters, antwoorden en metagegevens van een eindpunt worden onderzocht om een OpenAPI-aantekeningstype te maken dat wordt gebruikt om een eindpunt te beschrijven.

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

WithOpenApi aanroepen met parameters

De methode WithOpenApi accepteert een functie die kan worden gebruikt om de OpenAPI-aantekening te wijzigen. In de volgende code wordt bijvoorbeeld een beschrijving toegevoegd aan de eerste parameter van het eindpunt:

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

Eindpuntbeschrijvingen en samenvattingen opgeven

Minimale API's bieden nu ondersteuning voor aantekeningen maken van bewerkingen met beschrijvingen en samenvattingen voor het genereren van OpenAPI-specificaties. U kunt extensiemethoden WithDescription en WithSummary aanroepen of kenmerken [EndpointDescription] en [EndpointSummary]) gebruiken).

Zie OpenAPI in minimale API-apps voor meer informatie

Bestandsuploads met behulp van IFormFile en IFormFileCollection

Minimale API's ondersteunen nu het uploaden van bestanden met IFormFile en IFormFileCollection. De volgende code maakt gebruik van IFormFile en IFormFileCollection om het bestand te uploaden:

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

Geverifieerde aanvragen voor het uploaden van bestanden worden ondersteund met behulp van een Autorisatieheader, een clientcertificaatof een cookie-header.

Er is geen ingebouwde ondersteuning voor anti-namaking. Het kan echter worden geïmplementeerd met behulp van de IAntiforgery-service.

[AsParameters] kenmerk maakt parameterbinding mogelijk voor argumentlijsten

Het kenmerk [AsParameters] maakt parameterbinding voor argumentlijsten mogelijk. Zie Parameterbinding voor argumentlijsten met [AsParameters]voor meer informatie.

Minimale API's en API-controllers

Nieuwe service voor probleemdetails

De service voor probleemdetails implementeert de IProblemDetailsService-interface, die ondersteuning biedt voor het maken van probleemdetails voor HTTP-API's.

Zie Service voor probleemdetailsvoor meer informatie.

Routegroepen

Met de MapGroup-extensiemethode kunt u groepen eindpunten organiseren met een gemeenschappelijk voorvoegsel. Het vermindert terugkerende code en maakt het mogelijk om hele groepen eindpunten aan te passen met één aanroep naar methoden zoals RequireAuthorization en WithMetadata waarmee metagegevens van eindpuntenworden toegevoegd.

Met de volgende code worden bijvoorbeeld twee vergelijkbare groepen eindpunten gemaakt:

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

In dit scenario kunt u een relatief adres gebruiken voor de Location-header in het 201 Created resultaat:

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

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

De eerste groep eindpunten komt alleen overeen met aanvragen die zijn voorafgegaan door /public/todos en zijn toegankelijk zonder verificatie. De tweede groep eindpunten komt alleen overeen met aanvragen die zijn voorafgegaan door /private/todos en vereisen verificatie.

De QueryPrivateTodoseindpuntfilterfactory is een lokale functie waarmee de TodoDb parameters van de route-handler worden gewijzigd om toegang te krijgen tot privétodogegevens en deze op te slaan.

Routegroepen ondersteunen ook geneste groepen en complexe voorvoegselpatronen met routeparameters en beperkingen. In het volgende voorbeeld kan de routehandler die is toegewezen aan de user groep, de {org} en {group} routeparameters vastleggen die zijn gedefinieerd in de voorvoegsels van de buitenste groep.

Het voorvoegsel kan ook leeg zijn. Dit kan handig zijn voor het toevoegen van eindpuntmetagegevens of filters aan een groep eindpunten zonder het routepatroon te wijzigen.

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

Het toevoegen van filters of metagegevens aan een groep gedraagt zich op dezelfde manier als het afzonderlijk toevoegen van filters of metagegevens aan elk eindpunt voordat u extra filters of metagegevens toevoegt die mogelijk zijn toegevoegd aan een binnenste groep of specifiek eindpunt.

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

In het bovenstaande voorbeeld registreert het buitenste filter de binnenkomende aanvraag voordat het binnenste filter de kans krijgt om dat te doen, hoewel het binnenste filter als tweede is toegevoegd. Omdat de filters zijn toegepast op verschillende groepen, maakt de volgorde die ze ten opzichte van elkaar zijn toegevoegd niet uit. De volgorde waarin filters worden toegevoegd, maakt uit of ze op dezelfde groep of een specifiek eindpunt worden toegepast.

Een aanvraag voor /outer/inner/ meldt het volgende:

/outer group filter
/inner group filter
MapGet filter

gRPC

JSON-transcodering

gRPC JSON-transcodering is een extensie voor ASP.NET Core waarmee RESTful JSON-API's voor gRPC-services worden gemaakt. gRPC JSON-transcodering maakt het volgende mogelijk:

  • Apps voor het aanroepen van gRPC-services met vertrouwde HTTP-concepten.
  • ASP.NET Core gRPC-apps ter ondersteuning van zowel gRPC- als RESTful JSON-API's zonder functionaliteit te repliceren.
  • Experimentele ondersteuning voor het genereren van OpenAPI op basis van transcoded RESTful-API's door integratie met Swashbuckle.

Zie gRPC JSON-transcodering in ASP.NET Core gRPC-apps en OpenAPI gebruiken met gRPC JSON-transcodering ASP.NET Core-appsvoor meer informatie.

gRPC-gezondheidscontroles in ASP.NET Core

Het gRPC-statuscontroleprotocol is een standaard voor het rapporteren van de status van gRPC-server-apps. Een app biedt gezondheidscontroles via een gRPC-service. Ze worden meestal gebruikt met een externe bewakingsservice om de status van een app te controleren.

gRPC ASP.NET Core heeft ingebouwde ondersteuning toegevoegd voor gRPC-statuscontroles met het Grpc.AspNetCore.HealthChecks-pakket. Resultaten van .NET-statuscontroles worden aan aanroepers gerapporteerd.

Zie gRPC-statuscontroles in ASP.NET Corevoor meer informatie.

Verbeterde ondersteuning voor inloggegevens voor oproepen

Aanroepreferenties zijn de aanbevolen manier om een gRPC-client te configureren om een verificatietoken naar de server te verzenden. gRPC-clients ondersteunen twee nieuwe functies om aanroepreferenties eenvoudiger te gebruiken:

  • Ondersteuning voor oproep referenties met plaintext-verbindingen. Voorheen heeft een gRPC-aanroep alleen aanroepreferenties verzonden als de verbinding is beveiligd met TLS. Met een nieuwe instelling op GrpcChannelOptions, UnsafeUseInsecureChannelCallCredentialsgenoemd, kan dit gedrag worden aangepast. Er zijn beveiligingsproblemen voor het niet beveiligen van een verbinding met TLS.
  • Er is een nieuwe methode genaamd AddCallCredentials beschikbaar met de gRPC-client-factory. AddCallCredentials is een snelle manier om aanroepreferenties voor een gRPC-client te configureren en goed te integreren met afhankelijkheidsinjectie (DI).

Met de volgende code configureert u de gRPC-clientfactory om Authorization metagegevens te verzenden:

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

Voor meer informatie, zie Een bearer-token configureren met de gRPC-clientfactory.

SignalR

Clientresultaten

De server ondersteunt nu het aanvragen van een resultaat van een client. Hiervoor moet de server ISingleClientProxy.InvokeAsync gebruiken en moet de client een resultaat retourneren van de .On handler. Sterk getypte hubs kunnen ook waarden retourneren van interfacemethoden.

Voor meer informatie, zie Clientresultaten

Afhankelijkheidsinjectie voor SignalR hub-methoden

SignalR hubmethoden bieden nu ondersteuning voor het injecteren van services via afhankelijkheidsinjectie (DI).

Hubconstructors kunnen services van DI accepteren als parameters, die kunnen worden opgeslagen in eigenschappen in de klasse voor gebruik in een hubmethode. Zie Services injecteren in een hub- voor meer informatie

Blazor

Locatie wijzigen van gebeurtenissen en navigatiestatus afhandelen

In .NET 7 ondersteunt Blazor locatie veranderende gebeurtenissen en het onderhouden van de navigatiestatus. Hiermee kunt u gebruikers waarschuwen over niet-opgeslagen werk of gerelateerde acties uitvoeren wanneer de gebruiker een paginanavigatie uitvoert.

Zie de volgende secties van het artikel Routering en navigatie voor meer informatie:

Lege Blazor projectsjablonen

Blazor heeft twee nieuwe projectsjablonen om te beginnen met een lege lei. De nieuwe Blazor Server App Empty en Blazor WebAssembly App Empty projectsjablonen zijn net als hun niet-lege tegenhangers, maar zonder voorbeeldcode. Deze lege sjablonen bevatten alleen een basisstartpagina en we hebben Bootstrap verwijderd, zodat u kunt beginnen met een ander CSS-framework.

Zie de volgende artikelen voor meer informatie:

aangepaste elementen Blazor

Met het Microsoft.AspNetCore.Components.CustomElements-pakket kunt u aangepaste DOM-elementen op basis van standaarden bouwen met behulp van Blazor.

Zie ASP.NET Core Razor-onderdelenvoor meer informatie.

Modificeerders binden (@bind:after, @bind:get, @bind:set)

Belangrijk

De @bind:after/@bind:get/@bind:set-functies ontvangen op dit moment verdere updates. Als u wilt profiteren van de nieuwste updates, controleert u of u de nieuwste SDK-hebt geïnstalleerd.

Het gebruiken van een event callback-parameter ([Parameter] public EventCallback<string> ValueChanged { get; set; }) wordt niet ondersteund. Geef in plaats daarvan een Action-retour- of Task-retourmethode door aan @bind:set/@bind:after.

Zie de volgende bronnen voor meer informatie:

In .NET 7 kunt u asynchrone logica uitvoeren nadat een bindingsgebeurtenis is voltooid met behulp van de nieuwe @bind:after modifier. In het volgende voorbeeld wordt de PerformSearch asynchrone methode automatisch uitgevoerd nadat wijzigingen in de zoektekst zijn gedetecteerd:

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

@code {
    private string searchText;

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

In .NET 7 is het ook eenvoudiger om binding in te stellen voor onderdeelparameters. Onderdelen kunnen tweerichtingsgegevensbinding ondersteunen door een paar parameters te definiëren:

  • @bind:get: hiermee geeft u de waarde op die moet worden gebonden.
  • @bind:set: hiermee geeft u een callback op voor wanneer de waarde wordt gewijzigd.

De @bind:get en @bind:set modifiers worden altijd samen gebruikt.

Voorbeelden:

@* 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; }
}

Zie InputTextvoor meer informatie over het Blazor onderdeel.

Verbeteringen aan Hot Reload

In .NET 7 bevat hot reload-ondersteuning het volgende:

  • Onderdelen stellen hun parameters opnieuw in op hun standaardwaarden wanneer een waarde wordt verwijderd.
  • Blazor WebAssembly:
    • Nieuwe typen toevoegen.
    • Geneste klassen toevoegen.
    • Voeg statische methoden en exemplaarmethoden toe aan bestaande typen.
    • Voeg statische velden en methoden toe aan bestaande typen.
    • Voeg statische lambdas toe aan bestaande methoden.
    • Voeg lambdas toe die this vastleggen aan bestaande methoden die eerder this vastlegden.

Dynamische verificatieaanvragen met MSAL in Blazor WebAssembly

Nieuw in .NET 7 biedt Blazor WebAssembly ondersteuning voor het maken van dynamische verificatieaanvragen tijdens runtime met aangepaste parameters voor het afhandelen van geavanceerde verificatiescenario's.

Zie de volgende artikelen voor meer informatie:

Verbeteringen voor foutopsporing Blazor WebAssembly

Blazor WebAssembly foutopsporing heeft de volgende verbeteringen:

  • Ondersteuning voor de instelling Just My Code om typeleden weer te geven of te verbergen die niet afkomstig zijn van gebruikerscode.
  • Ondersteuning voor het inspecteren van multidimensionale matrices.
  • Aanroepstack toont nu de juiste naam voor asynchrone methoden.
  • Verbeterde evaluatie van expressies.
  • Juiste verwerking van het new trefwoord voor afgeleide leden.
  • Ondersteuning voor foutopsporingskenmerken in System.Diagnostics.

System.Security.Cryptography ondersteuning voor WebAssembly

.NET 6 ondersteunde de SHA-familie van hash-algoritmen bij het uitvoeren op WebAssembly. .NET 7 maakt meer cryptografische algoritmen mogelijk door gebruik te maken van SubtleCrypto, indien mogelijk, en terug te vallen op een .NET-implementatie wanneer SubtleCrypto niet kan worden gebruikt. De volgende algoritmen worden ondersteund op WebAssembly in .NET 7:

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

Zie voor meer informatie. Ontwikkelaars die zich richten op browser-wasm kunnen de Web Crypto-API's gebruiken (dotnet/runtime #40074).

Diensten injecteren in aangepaste validatie-attributen.

U kunt nu diensten injecteren in aangepaste validatiekenmerken. Blazor stelt de ValidationContext in, zodat deze kan worden gebruikt als serviceprovider.

Zie ASP.NET Core Blazor formuliervalidatievoor meer informatie.

Input* onderdelen buiten de grenzen van EditContext/EditForm

De ingebouwde invoeronderdelen worden nu buiten een formulier ondersteund in Razor componentmarkup.

Zie ASP.NET Core Blazor invoeronderdelenvoor meer informatie.

Projectsjabloonwijzigingen

Toen .NET 6 vorig jaar werd uitgebracht, werd de HTML-opmaak van de _Host pagina (Pages/_Host.chstml) gesplitst tussen de _Host pagina en een nieuwe _Layout pagina (Pages/_Layout.chstml) in de projectsjabloon .NET 6 Blazor Server.

In .NET 7 is de HTML-markering opnieuw gekoppeld aan de _Host pagina in projectsjablonen.

Er zijn verschillende aanvullende wijzigingen aangebracht in de Blazor projectsjablonen. Het is niet haalbaar om elke wijziging in de sjablonen in de documentatie weer te geven. Zie Migreren van ASP.NET Core 6.0 naar 7.0als u een app naar .NET 7 wilt migreren om alle wijzigingen te implementeren.

Experimenteel QuickGrid-onderdeel

Het nieuwe QuickGrid-onderdeel biedt een handig gegevensrasteronderdeel voor de meest voorkomende vereisten en als referentiearchitectuur en prestatiebasislijn voor iedereen die Blazor gegevensrasteronderdelen bouwt.

Zie ASP.NET Core BlazorQuickGridcomponentvoor meer informatie.

Livedemo: QuickGrid voor Blazor voorbeeld-app

Virtualisatieverbeteringen

Virtualisatieverbeteringen in .NET 7:

  • Het Virtualize-onderdeel ondersteunt het gebruik van het document zelf als de scroll root, als alternatief voor het toepassen van een ander element waarbij overflow-y: scroll is toegepast.
  • Als de Virtualize-component binnen een element wordt geplaatst dat een specifieke naam van een onderliggende tag vereist, kunt u met SpacerElement de tagnaam van de virtualisatie-spacer ophalen of instellen.

Zie de volgende secties van het artikel Virtualization voor meer informatie:

updates voor MouseEventArgs

MovementX en MovementY zijn toegevoegd aan MouseEventArgs.

Zie ASP.NET Core Blazor event handlingvoor meer informatie.

Pagina voor het laden van nieuwe Blazor

De Blazor WebAssembly projectsjabloon heeft een nieuwe gebruikersinterface voor laden waarin de voortgang van het laden van de app wordt weergegeven.

Zie ASP.NET Core Blazor startupvoor meer informatie.

Verbeterde diagnose voor verificatie in Blazor WebAssembly

Gedetailleerde logboekregistratie is beschikbaar om verificatieproblemen in Blazor WebAssembly-apps vast te stellen.

Zie ASP.NET Core Blazor loggingvoor meer informatie.

JavaScript-interoperabiliteit op WebAssembly

JavaScript [JSImport]/[JSExport] interop-API is een nieuw mechanisme op laag niveau voor het gebruik van .NET in Blazor WebAssembly- en JavaScript-apps. Met deze nieuwe JavaScript-interoperabiliteitsfunctie kunt u .NET-code aanroepen vanuit JavaScript met behulp van de .NET WebAssembly-runtime en javaScript-functionaliteit aanroepen vanuit .NET zonder enige afhankelijkheid van het Blazor UI-onderdeelmodel.

Voor meer informatie:

Voorwaardelijke registratie van de verificatiestatusprovider

Vóór de release van .NET 7 werd AuthenticationStateProvider geregistreerd in de servicecontainer met AddScoped. Hierdoor is het lastig om fouten in apps op te sporen, omdat er een specifieke volgorde van serviceregistraties is afgedwongen bij het leveren van een aangepaste implementatie. Vanwege interne frameworkwijzigingen in de loop van de tijd is het niet meer nodig om AuthenticationStateProvider te registreren bij AddScoped.

Breng in ontwikkelaarscode de volgende wijziging aan in de serviceregistratie van de verificatiestatusprovider:

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

In het voorgaande voorbeeld is ExternalAuthStateProvider de service-implementatie van de ontwikkelaar.

Verbeteringen aan de .NET WebAssembly-buildhulpprogramma's

Nieuwe functies in de wasm-tools-workload voor .NET 7 die helpen de prestaties te verbeteren en uitzonderingen af te handelen:

Voor meer informatie, zie ASP.NET Core Blazor WebAssembly build tools en ahead-of-time (AOT) compilatie.

Blazor Hybrid

Externe URLs

Er is een optie toegevoegd waarmee externe webpagina's in de browser kunnen worden geopend.

Zie ASP.NET Core Blazor Hybrid routering en navigatievoor meer informatie.

Veiligheid

Er zijn nieuwe richtlijnen beschikbaar voor Blazor Hybrid beveiligingsscenario's. Zie de volgende artikelen voor meer informatie:

Prestatie

Middleware voor uitvoercache

Uitvoercache is een nieuwe middleware waarmee reacties van een web-app worden opgeslagen en deze worden verwerkt vanuit een cache in plaats van ze elke keer te berekenen. Outputcaching verschilt van responscaching op de volgende manieren:

  • Het cachegedrag kan worden geconfigureerd op de server.
  • Cachevermeldingen kunnen programmatisch ongeldig worden gemaakt.
  • Het vergrendelen van resources beperkt het risico van cachestempel en dondert.
  • Cachevalidatie betekent dat de server een 304 Not Modified HTTP-statuscode kan retourneren in plaats van een hoofdtekst van het antwoord in de cache.
  • Het opslagmedium voor de cache is uitbreidbaar.

Zie voor meer informatie Overzicht van caching en Output caching-middleware.

HTTP/3-verbeteringen

Deze release:

  • Maakt HTTP/3 volledig ondersteund door ASP.NET Core, het is niet langer experimenteel.
  • Verbetert Kestrelondersteuning voor HTTP/3. De twee belangrijkste gebieden van verbetering zijn functiepariteit met HTTP/1.1 en HTTP/2 en prestaties.
  • Biedt volledige ondersteuning voor UseHttps(ListenOptions, X509Certificate2) met HTTP/3. Kestrel biedt geavanceerde opties voor het configureren van verbindingscertificaten, zoals het koppelen aan SNI-(Server Name Indication).
  • Voegt ondersteuning toe voor HTTP/3 op HTTP.sys en IIS-.

In het volgende voorbeeld ziet u hoe u een SNI-callback gebruikt om TLS-opties op te lossen:

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

Belangrijke werkzaamheden zijn uitgevoerd in .NET 7 om HTTP/3-toewijzingen te verminderen. U kunt enkele van deze verbeteringen bekijken in de volgende GitHub PR's:

Verbeteringen in de prestaties van HTTP/2

.NET 7 introduceert een aanzienlijke herarchitectuur van de wijze waarop Kestrel HTTP/2-aanvragen verwerkt. ASP.NET Core-apps met drukke HTTP/2-verbindingen hebben minder CPU-gebruik en hogere doorvoer.

Voorheen was de implementatie van HTTP/2-multiplexing afhankelijk van een -vergrendeling dat bepaalt welke aanvraag kan schrijven naar de onderliggende TCP-verbinding. Een threadveilige wachtrij vervangt de schrijfvergrendeling. In plaats van dat threads vochten om de schrijfvergrendeling te krijgen, worden aanvragen nu in de wachtrij geplaatst en worden ze door een speciale verwerker verwerkt. Eerder verspilde CPU-resources zijn beschikbaar voor de rest van de app.

Een plek waar deze verbeteringen kunnen worden opgemerkt, is in gRPC, een populair RPC-framework dat gebruikmaakt van HTTP/2. Kestrel + gRPC-benchmarks laten een aanzienlijke verbetering zien:

streamingprestaties van gRPC-servers

Wijzigingen zijn aangebracht in de HTTP/2-framecode die de prestaties verbetert wanneer er meerdere streams gegevens willen schrijven op één HTTP/2-verbinding. We verzenden nu TLS-werk naar de threadgroep en geven sneller een schrijfvergrendeling vrij die andere streams kunnen verkrijgen om hun gegevens te schrijven. De vermindering van wachttijden kan aanzienlijke prestatieverbeteringen opleveren in gevallen waarin er conflicten zijn voor deze schrijfvergrendeling. Een gRPC-benchmark met 70 streams op één verbinding (met TLS) toonde een verbetering van circa 15% verbetering in aanvragen per seconde (RPS) met deze wijziging.

Ondersteuning voor Http/2 WebSockets

.NET 7 introduceert WebSockets via HTTP/2-ondersteuning voor Kestrel, de SignalR JavaScript-client en SignalR met Blazor WebAssembly.

Het gebruik van WebSockets via HTTP/2 maakt gebruik van nieuwe functies, zoals:

  • Headercompressie.
  • Multiplexing, wat de tijd en resources vermindert die nodig zijn bij het indienen van meerdere aanvragen naar de server.

Deze ondersteunde functies zijn beschikbaar in Kestrel op alle platforms waarvoor HTTP/2 is ingeschakeld. De versieonderhandeling is automatisch in browsers en Kestrel, dus er zijn geen nieuwe API's nodig.

Voor meer informatie, zie Http/2 WebSockets-ondersteuning.

Kestrel prestatieverbeteringen op machines met hoge kernen

Kestrel gebruikt ConcurrentQueue<T> voor veel doeleinden. Eén doel is het plannen van I/O-bewerkingen in Kestrel's standaard Sockettransport. Het partitioneren van de ConcurrentQueue op basis van de bijbehorende socket vermindert conflicten en verhoogt de doorvoer op computers met veel CPU-kernen.

Profilering op high core-machines op .NET 6 toonde aanzienlijke wedijver aan in een van de andere Kestrel exemplaren van ConcurrentQueue, de PinnedMemoryPool die Kestrel gebruikt voor het cachen van bytebuffers.

In .NET 7 wordt de geheugenpool van Kestrelop dezelfde manier gepartitioneerd als de I/O-wachtrij, wat leidt tot een veel lagere mate van conflicten en een hogere doorvoer op machines met een groot aantal cores. Op de ARM64-VM's met 80 cores zien we meer dan 500% verbetering in verwerkingen per seconde (RPS) in de TechEmpower plaintext benchmark. Op 48-core AMD-VMs is de prestatieverbetering bijna 100% in onze HTTPS JSON-benchmark.

ServerReady gebeurtenis om de opstarttijd te meten

Apps die gebruikmaken van EventSource kunnen de opstarttijd meten om de opstartprestaties te begrijpen en te optimaliseren. De nieuwe ServerReady gebeurtenis in Microsoft.AspNetCore.Hosting vertegenwoordigt het punt waarop de server gereed is om te reageren op aanvragen.

Server

Nieuwe ServerReady-gebeurtenis voor het meten van opstarttijd

De ServerReady-gebeurtenis is toegevoegd om de opstarttijd van ASP.NET Core apps te meten.

IIS

Schaduwkopie in IIS

Schaduwkopie van app-assembly's naar de ASP.NET Core Module (ANCM) voor IIS kan een betere eindgebruikerservaring bieden dan de app te stoppen door een offlinebestand voor een app te implementeren.

Zie Schaduw kopiëren in IISvoor meer informatie.

Allerlei

volledige verbeteringen in de certificaatketen Kestrel

HttpsConnectionAdapterOptions- heeft een nieuwe ServerCertificateChain- van het type X509Certificate2Collection, waardoor het eenvoudiger is om certificaatketens te valideren door een volledige keten met tussenliggende certificaten op te geven. Zie dotnet/aspnetcore#21513 voor meer informatie.

dotnet watch

Verbeterde console-uitvoer voor dotnet watch

De console-uitvoer van dotnet watch is verbeterd om beter aan te sluiten bij de logging van ASP.NET Core en zich te onderscheiden met 😮emoji's😍.

Hier volgt een voorbeeld van hoe de nieuwe uitvoer eruitziet:

uitvoer voor dotnet watch

Zie deze GitHub-pull-aanvraagvoor meer informatie.

Dotnet-horloge configureren om altijd opnieuw op te starten voor onbeleefde bewerkingen

Drastische bewerkingen zijn bewerkingen die niet direct kunnen worden herladen. Als u dotnet watch wilt configureren om altijd opnieuw op te starten zonder te vragen om onbeleefde bewerkingen, stelt u de omgevingsvariabele DOTNET_WATCH_RESTART_ON_RUDE_EDIT in op true.

Donkere modus voor ontwikkelaarsonderzonderingspagina

Ondersteuning voor donkere modus is toegevoegd aan de uitzonderingspagina voor ontwikkelaars, dankzij een bijdrage van Patrick Westerhoff. Als u de donkere modus in een browser wilt testen, stelt u op de pagina ontwikkelhulpprogramma's de modus in op donker. Bijvoorbeeld in Firefox:

F12 tools FF donkere modus

In Chrome:

F12-hulpprogramma's Chrome donkere modus

Optie projectsjabloon voor het gebruik van de methode Program.Main in plaats van instructies op het hoogste niveau

De .NET 7-sjablonen bevatten een optie om geen gebruik te maken van -instructies op het hoogste niveau en om een namespace en een Main-methode te genereren die gedeclareerd is op een Program-klasse.

Gebruik de .NET CLI met behulp van de optie --use-program-main:

dotnet new web --use-program-main

Schakel in Visual Studio het selectievakje Gebruik geen topniveaudeclaraties in tijdens het maken van het project:

selectievakje

Bijgewerkte Angular- en React-sjablonen

De Angular-projectsjabloon is bijgewerkt naar Angular 14. De React-projectsjabloon is bijgewerkt naar React 18.2.

JSON Web Tokens beheren tijdens de ontwikkeling met dotnet user-jwts

Met het nieuwe opdrachtregelprogramma voor dotnet user-jwts kunt u app-specifieke lokale JSON-webtokens (JWT's) maken en beheren. Zie JSON-webtokens beheren in ontwikkeling met dotnet user-jwtsvoor meer informatie.

Ondersteuning voor aanvullende aanvraagheaders in W3CLogger

U kunt nu extra aanvraagheaders specificeren om vast te leggen door AdditionalRequestHeaders() op W3CLoggerOptionsaan te roepen bij het gebruik van de W3C-logger.

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

Zie W3CLogger-optiesvoor meer informatie.

Decompressie aanvragen

De nieuwe decompressie-middleware voor verzoeken:

  • Hiermee kunnen API-eindpunten aanvragen accepteren met gecomprimeerde inhoud.
  • Gebruikt de Content-Encoding HTTP-header om aanvragen die gecomprimeerde inhoud bevatten, automatisch te identificeren en decomprimeren.
  • Hiermee hoeft u geen code te schrijven om gecomprimeerde aanvragen te verwerken.

Zie Request decompression middlewarevoor meer informatie.