Nyheter i ASP.NET Core 7.0
Den här artikeln belyser de viktigaste ändringarna i ASP.NET Core 7.0 med länkar till relevant dokumentation.
Hastighetsbegränsning av mellanprogram i ASP.NET Core
Det Microsoft.AspNetCore.RateLimiting
-mellanprogrammet ger ett mellanprogram för hastighetsbegränsning. Appar konfigurerar principer för hastighetsbegränsning och kopplar sedan principerna till slutpunkter. Mer information finns i Hastighetsbegränsning för mellanprogram i ASP.NET Core.
Autentisering använder ett enda schema som DefaultScheme
Som en del av arbetet med att förenkla autentiseringen, när det bara finns ett enda autentiseringsschema registrerat, används det automatiskt som DefaultScheme och behöver inte anges. Mer information finns i DefaultScheme.
MVC- och Razor-sidor
Stöd för nullbara modeller i MVC-vyer och Razor-sidor
Nullsid- och vymodeller stöds för att förbättra upplevelsen vid kontroll av null-tillstånd med ASP.NET Core-appar.
@model Product?
Binda med IParsable<T>.TryParse
i MVC- och API-styrenheter
API:et IParsable<TSelf>.TryParse
stöder parametervärden för bindningskontrollantåtgärd. Mer information finns i Bind med IParsable<T>.TryParse
.
Anpassa värdet för cookie medgivande
I ASP.NET Core-versioner tidigare än 7 använder cookie medgivandeverifiering det cookie värdet yes
för att ange medgivande. Nu kan du ange det värde som representerar medgivande. Du kan till exempel använda true
i stället för 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();
Mer information finns i Anpassa cookie värdet för samtycke.
API-kontrollanter
Parameterbindning med DI i API-kontrollanter
Parameterbindning för API-kontrollantåtgärder binder parametrar via beroendeinmatning när typen konfigureras som en tjänst. Det innebär att det inte längre krävs att uttryckligen tillämpa attributet [FromServices]
på en parameter. I följande kod returnerar båda åtgärderna tiden:
[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);
}
I sällsynta fall kan automatisk DI bryta appar som har en typ i DI som också accepteras i en API-kontrollantåtgärdsmetod. Det är inte vanligt att ha en typ i DI och som argument i en API-kontrollantåtgärd. Om du vill inaktivera automatisk bindning av parametrar anger du 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();
I ASP.NET Core 7.0 kontrolleras typer i DI vid appstart med IServiceProviderIsService för att avgöra om ett argument i en API-kontrollantåtgärd kommer från DI eller från andra källor.
Den nya mekanismen för att härleda bindningskällan för API Controller-åtgärdsparametrar använder följande regler:
- En tidigare specificerad
BindingInfo.BindingSource
skrivs aldrig över. - En komplex typparameter, registrerad i DI-containern, tilldelas
BindingSource.Services
. - En komplex typparameter, som inte är registrerad i DI-containern, tilldelas
BindingSource.Body
. - En parameter med ett namn som visas som ett vägvärde i någon rutmall tilldelas
BindingSource.Path
. - Alla andra parametrar är
BindingSource.Query
.
JSON-egenskapsnamn i valideringsfel
När ett valideringsfel inträffar skapar modellverifiering som standard en ModelStateDictionary med egenskapsnamnet som felnyckel. Vissa appar, till exempel ensidiga applikationer, drar fördel av att använda JSON-egenskapsnamn för valideringsfel som genereras från webb-API:er. Följande kod konfigurerar validering för att använda SystemTextJsonValidationMetadataProvider
för att använda JSON-egenskapsnamn:
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();
Följande kod konfigurerar validering för att använda NewtonsoftJsonValidationMetadataProvider
för att använda JSON-egenskapsnamn när du använder 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();
Mer information finns i Använda JSON-egenskapsnamn i verifieringsfel
Minimala API:er
Filter i minimala API-appar
Med minimala API-filter kan utvecklare implementera affärslogik som stöder:
- Kör kod före och efter routningshanteraren.
- Inspektera och ändra parametrar som tillhandahålls vid ett routahanterarens anrop.
- Fånga upp svarsbeteendet hos en routerhanterare.
Filter kan vara användbara i följande scenarier:
- Validera parametrarna och innehållet i begäran som skickas till en slutpunkt.
- Loggningsinformation om begäran och svar.
- Verifiera att en begäran riktar sig till en API-version som stöds.
Mer information finns i filter i Minimala API-appar
Binda matriser och strängvärden från rubriker och frågesträngar
I ASP.NET 7 stöds bindning av frågesträngar till en matris med primitiva typer, strängmatriser och 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]}");
Bindning av frågesträngar eller sidhuvudvärden till en matris med komplexa typer stöds när typen har TryParse
implementerats. För mer information, se Bindning av matriser och strängvärden från rubriker och frågesträngar.
Mer information finns i Lägg till slutpunktssammanfattning eller beskrivning.
Binda begärandetexten som en Stream
eller PipeReader
Begärandetexten kan bindas som en Stream
eller PipeReader
för att effektivt stödja scenarier där användaren måste bearbeta data och:
- Lagra data i bloblagring eller lagra data i en kötjänst.
- Bearbeta lagrade data med en arbetsprocess eller molnfunktion.
Data kan till exempel köas i Azure Queue Storage eller lagras i Azure Blob Storage.
Mer information finns i Binda begärandetexten som en Stream
eller PipeReader
Nya överlagringar i Results.Stream
Vi introducerade nya Results.Stream
överlagringar för att hantera scenarier som behöver åtkomst till den underliggande HTTP-svarsströmmen utan buffring. Dessa överlagringar förbättrar också fall där ett API strömmar data till HTTP-svarsströmmen, till exempel från Azure Blob Storage. I följande exempel används ImageSharp- för att returnera en reducerad storlek på den angivna bilden:
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);
}
Mer information finns i Stream-exempel
Inskrivna resultat för minimala API:er
I .NET 6 introducerades IResult-gränssnittet för att representera värden som returneras från minimala API:er som inte använder implicit stöd för JSON-serialisering av det returnerade objektet till HTTP-svaret. Klassen static Results används för att skapa varierande IResult
objekt som representerar olika typer av svar. Du kan till exempel ange svarsstatuskoden eller omdirigera till en annan URL. Den IResult
implementering av ramverkstyper som returnerades från dessa metoder var dock intern, vilket gör det svårt att verifiera den specifika IResult
typ som returneras från metoder i ett enhetstest.
I .NET 7 är de typer som implementerar IResult
offentliga, vilket möjliggör typkontroller vid testning. Till exempel:
[TestClass()]
public class WeatherApiTests
{
[TestMethod()]
public void MapWeatherApiTest()
{
var result = WeatherApi.GetAllWeathers();
Assert.IsInstanceOfType(result, typeof(Ok<WeatherForecast[]>));
}
}
Förbättrad enhetstestbarhet för minimala routningshanterare
IResult implementeringstyper är nu offentligt tillgängliga i Microsoft.AspNetCore.Http.HttpResults namnområdet. De IResult
implementeringstyperna kan användas för att enhetstesta minimala routningshanterare när du använder namngivna metoder i stället för lambdas.
Följande kod använder klassen Ok<TValue>
:
[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);
}
Mer information finns i IResult
implementeringstyper.
Nya HttpResult-gränssnitt
Följande gränssnitt i namnområdet Microsoft.AspNetCore.Http ger ett sätt att identifiera IResult
typen under körning, vilket är ett vanligt mönster i filterimplementeringar.
- IContentTypeHttpResult
- IFileHttpResult
- INestedHttpResult
- IStatusCodeHttpResult
- IValueHttpResult
- IValueHttpResult<TValue>
Mer information finns i IHttpResult-gränssnitt.
OpenAPI-förbättringar för minimala API:er
Microsoft.AspNetCore.OpenApi
NuGet-paket
Microsoft.AspNetCore.OpenApi
-paketet tillåter interaktioner med OpenAPI-specifikationer för slutpunkter. Paketet fungerar som en länk mellan OpenAPI-modellerna som definieras i Microsoft.AspNetCore.OpenApi
-paketet och de slutpunkter som definieras i Minimala API:er. Paketet tillhandahåller ett API som undersöker en slutpunkts parametrar, svar och metadata för att konstruera en OpenAPI-anteckningstyp som används för att beskriva en slutpunkt.
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();
Anropa WithOpenApi
med parametrar
Metoden WithOpenApi
accepterar en funktion som kan användas för att ändra OpenAPI-kommentaren. I följande kod läggs till exempel en beskrivning till i slutpunktens första parameter:
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;
});
Ange slutpunktsbeskrivningar och sammanfattningar
Minimala API:er stöder nu anteckningar med beskrivningar och sammanfattningar för generering av OpenAPI-specifikation. Du kan anropa tilläggsmetoder WithDescription och WithSummary eller använda attribut [EndpointDescription] och [EndpointSummary]).
Mer information finns i OpenAPI i minimala API-appar
Filuppladdningar med IFormFile och IFormFileCollection
Minimala API:er stöder nu filuppladdning med IFormFile
och IFormFileCollection
. Följande kod använder IFormFile och IFormFileCollection för att ladda upp filen:
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();
Autentiserade filuppladdningsbegäranden stöds med hjälp av ett auktoriseringshuvud, ett klientcertifikateller ett cookie-huvud.
Det finns inget inbyggt stöd för falskningsskydd. Den kan dock implementeras med hjälp av IAntiforgery
-tjänsten.
[AsParameters]
-attributet aktiverar parameterbindning för argumentlistor
Attributet [AsParameters]
aktiverar parameterbindning för argumentlistor. Mer information finns i Parameterbindning för argumentlistor med [AsParameters]
.
Minimala API:er och API-kontrollanter
Ny probleminformationstjänst
Probleminformationstjänsten implementerar IProblemDetailsService-gränssnittet, som har stöd för att skapa probleminformation för HTTP-API:er.
Mer information finns i Probleminformationstjänsten.
Routtgrupper
Tilläggsmetoden MapGroup hjälper till att organisera grupper av slutpunkter med ett gemensamt prefix. Det minskar repetitiv kod och gör det möjligt att anpassa hela grupper av slutpunkter med ett enda anrop till metoder som RequireAuthorization och WithMetadata som lägger till slutpunktsmetadata.
Följande kod skapar till exempel två liknande grupper av slutpunkter:
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;
}
I det här scenariot kan du använda en relativ adress för Location
-huvudet i 201 Created
resultat:
public static async Task<Created<Todo>> CreateTodo(Todo todo, TodoDb database)
{
await database.AddAsync(todo);
await database.SaveChangesAsync();
return TypedResults.Created($"{todo.Id}", todo);
}
Den första gruppen med slutpunkter matchar endast begäranden som är prefix med /public/todos
och är tillgängliga utan autentisering. Den andra gruppen med slutpunkter matchar endast begäranden som är prefix med /private/todos
och kräver autentisering.
QueryPrivateTodos
slutpunktsfilterfabriken är en lokal funktion som ändrar routningshanterarens TodoDb
parametrar för att tillåta åtkomst till och lagra privata data.
Routningsgrupper stöder också kapslade grupper och komplexa prefixmönster med vägparametrar och begränsningar. I följande exempel kan routhanteraren som mappas till gruppen user
fånga de {org}
- och {group}
-routningsparametrar som definierats i de yttre gruppens prefix.
Prefixet kan också vara tomt. Detta kan vara användbart för att lägga till slutpunktsmetadata eller filter till en grupp slutpunkter utan att ändra vägmönstret.
var all = app.MapGroup("").WithOpenApi();
var org = all.MapGroup("{org}");
var user = org.MapGroup("{user}");
user.MapGet("", (string org, string user) => $"{org}/{user}");
Att lägga till filter eller metadata i en grupp fungerar på samma sätt som att lägga till dem individuellt i varje slutpunkt innan du lägger till extra filter eller metadata som kan ha lagts till i en inre grupp eller en specifik slutpunkt.
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);
});
I exemplet ovan loggar det yttre filtret den inkommande begäran före det inre filtret trots att det lades till tvåa. Eftersom filtren tillämpades på olika grupper spelar det ingen roll vilken ordning de lades till i förhållande till varandra. Orderfiltren som läggs till spelar roll om de tillämpas på samma grupp eller specifika slutpunkt.
En begäran om att /outer/inner/
loggar följande:
/outer group filter
/inner group filter
MapGet filter
gRPC
JSON-transkodning
gRPC JSON-transkodning är ett tillägg för ASP.NET Core som skapar RESTful JSON-API:er för gRPC-tjänster. gRPC JSON-omkodning tillåter:
- Appar som anropar gRPC-tjänster med välbekanta HTTP-begrepp.
- ASP.NET Core gRPC-appar som stöder både gRPC- och RESTful JSON-API:er utan att replikera funktioner.
- Experimentellt stöd för att generera OpenAPI från transkodade RESTful-API:er genom att integrera med Swashbuckle.
Mer information finns i gRPC JSON-omkodning i ASP.NET Core gRPC-appar och Använda OpenAPI med gRPC JSON-transkodning ASP.NET Core-appar.
gRPC-hälsokontroller i ASP.NET Core
Protokollet gRPC-hälsokontroll är en standard för rapportering av hälsotillståndet för gRPC-serverappar. En app erbjuder hälsokontroller som en gRPC-tjänst. De används vanligtvis med en extern övervakningstjänst för att kontrollera status för en app.
gRPC ASP.NET Core har lagt till inbyggt stöd för gRPC-hälsokontroller med Grpc.AspNetCore.HealthChecks
-paketet. Resultat från .NET-hälsokontroller rapporteras till de som anropar.
För mer information, se gRPC-hälsokontroller i ASP.NET Core.
Förbättrat stöd för autentiseringsuppgifter för samtal
Autentiseringsuppgifter för anrop är det rekommenderade sättet att konfigurera en gRPC-klient för att skicka en autentiseringstoken till servern. gRPC-klienter har stöd för två nya funktioner för att göra anropsuppgifterna enklare att använda:
- Stöd för autentiseringsuppgifter för samtal med klartextanslutningar. Tidigare skickade ett gRPC-anrop endast autentiseringsuppgifter för samtal om anslutningen var skyddad med TLS. Med en ny inställning för
GrpcChannelOptions
, som kallasUnsafeUseInsecureChannelCallCredentials
, kan det här beteendet anpassas. Det finns säkerhetsaspekter för att inte skydda en anslutning med TLS. - En ny metod med namnet
AddCallCredentials
är tillgänglig med gRPC-klientfabrik.AddCallCredentials
är ett snabbt sätt att konfigurera autentiseringsuppgifter för anrop för en gRPC-klient och integrerar väl med beroendeinmatning (DI).
Följande kod konfigurerar gRPC-klientfabriken för att skicka Authorization
metadata:
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;
});
För mer information, se Konfigurera en bearertoken med gRPC-klientfabriken.
SignalR
Klientresultat
Servern har nu stöd för att begära ett resultat från en klient. Detta kräver att servern använder ISingleClientProxy.InvokeAsync
och att klienten ska returnera ett resultat från sin .On
-hanterare. Starkt typade hubbar kan också returnera värden från gränssnittsmetoder.
Mer information finns i klientresultat
Beroendeinmatning för SignalR hubbmetoder
SignalR hubbmetoder stöder nu inmatning av tjänster via beroendeinmatning (DI).
Hubbkonstruktorer kan acceptera tjänster från DI som parametrar, som kan lagras i egenskaper i klassen för användning i en hubbmetod. Mer information finns i Mata in tjänster i en hubb
Blazor
Hantera platsändringshändelser och navigeringstillstånd
I .NET 7 stöder Blazor platsändringshändelser och underhåll av navigeringstillstånd. På så sätt kan du varna användare om arbete som inte har sparats eller utföra relaterade åtgärder när användaren utför en sidnavigering.
Mer information finns i följande avsnitt i artikeln Routning och navigering:
Tomma Blazor projektmallar
Blazor har två nya projektmallar för att starta från en tom skiffer. De nya Blazor Server App Empty och Blazor WebAssembly App Empty-projektmallar är precis som deras icke-tomma motsvarigheter men utan exempelkod. De här tomma mallarna innehåller bara en grundläggande startsida och vi har tagit bort Bootstrap så att du kan börja med ett annat CSS-ramverk.
Mer information finns i följande artiklar:
Blazor specialanpassade element
Med Microsoft.AspNetCore.Components.CustomElements
-paketet kan du skapa standardbaserade anpassade DOM-element med hjälp av Blazor.
Mer information finns i ASP.NET Core Razor-komponenter.
Bindningsmodifierare (@bind:after
, @bind:get
, @bind:set
)
Viktig
De @bind:after
/@bind:get
/@bind:set
funktionerna får för närvarande ytterligare uppdateringar. Om du vill dra nytta av de senaste uppdateringarna bekräftar du att du har installerat senaste SDK-.
Det går inte att använda en händelseåteranropsparameter ([Parameter] public EventCallback<string> ValueChanged { get; set; }
). Skicka i stället en Action-returning- eller Task-returning-metod till @bind:set
/@bind:after
.
Mer information finns i följande resurser:
I .NET 7 kan du köra asynkron logik när en bindningshändelse har slutförts med hjälp av den nya @bind:after
-modifieraren. I följande exempel körs den PerformSearch
asynkrona metoden automatiskt när ändringar i söktexten har identifierats:
<input @bind="searchText" @bind:after="PerformSearch" />
@code {
private string searchText;
private async Task PerformSearch()
{
...
}
}
I .NET 7 är det också enklare att konfigurera bindning för komponentparametrar. Komponenter kan stödja dubbelriktad databindning genom att definiera ett par parametrar:
-
@bind:get
: Anger värdet som ska bindas. -
@bind:set
: Anger ett återanrop för när värdet ändras.
De @bind:get
och @bind:set
modifierare används alltid tillsammans.
Exempel:
@* 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; }
}
Mer information om komponenten InputText
finns i ASP.NET Core Blazor-indatakomponenter.
Förbättringar av hot reload
I .NET 7 innehåller stöd för frekvent omläsning följande:
- Komponenter återställer sina parametrar till sina standardvärden när ett värde tas bort.
-
Blazor WebAssembly:
- Lägg till nya typer.
- Lägg till kapslade klasser.
- Lägg till statiska metoder och instansmetoder i befintliga typer.
- Lägg till statiska fält och metoder i befintliga typer.
- Lägg till statiska lambdas i befintliga metoder.
- Lägg till lambdas som infångar
this
i befintliga metoder som tidigare redan infångadethis
.
Begäranden om dynamisk autentisering med MSAL i Blazor WebAssembly
Ny i .NET 7 har Blazor WebAssembly stöd för att skapa begäranden om dynamisk autentisering vid körning med anpassade parametrar för att hantera avancerade autentiseringsscenarier.
Mer information finns i följande artiklar:
- Secure ASP.NET Core Blazor WebAssembly
- ASP.NET Core Blazor WebAssembly ytterligare säkerhetsscenarier
Blazor WebAssembly felsökningsförbättringar
Blazor WebAssembly felsökning har följande förbättringar:
- Stöd för inställningen Just My Code för att visa eller dölja typmedlemmar som inte är från användarkoden.
- Stöd för att inspektera flerdimensionella matriser.
- Anropsstack visar nu rätt namn för asynkrona metoder.
- Förbättrad uttrycksutvärdering.
- Korrekt hantering av nyckelordet
new
på härledda medlemmar. - Stöd för felsökningsrelaterade attribut i
System.Diagnostics
.
System.Security.Cryptography
stöd på WebAssembly
.NET 6 har stöd för SHA-serien med hashalgoritmer när de körs på WebAssembly. .NET 7 möjliggör fler kryptografiska algoritmer genom att dra nytta av SubtleCrypto, när det är möjligt och återgå till en .NET-implementering när SubtleCrypto inte kan användas. Följande algoritmer stöds på WebAssembly i .NET 7:
- SHA1
- SHA256
- SHA384
- SHA512
- HMACSHA1
- HMACSHA256
- HMACSHA384
- HMACSHA512
- AES-CBC
- PBKDF2
- HKDF
Mer information finns i Utvecklare som riktar in sig på webbläsar-wasm kan använda API:er för webbkryptering (dotnet/runtime #40074).
Mata in tjänster i anpassade valideringsattribut
Du kan nu mata in tjänster i anpassade valideringsattribut.
Blazor konfigurerar ValidationContext
så att den kan användas som tjänstleverantör.
Mer information finns i ASP.NET Core Blazor formulärverifiering.
Input*
komponenter utanför en EditContext
/EditForm
De inbyggda indatakomponenterna stöds nu utanför ett formulär i Razor komponentmarkering.
Mer information hittar du i ASP.NET Core Blazor indatakomponenter.
Ändringar i projektmall
När .NET 6 släpptes förra året delades HTML-koden på sidan _Host
(Pages/_Host.chstml
) mellan sidan _Host
och en ny _Layout
sida (Pages/_Layout.chstml
) i projektmallen .NET 6 Blazor Server.
I .NET 7 har HTML-koden kombinerats med sidan _Host
i projektmallar.
Flera ytterligare ändringar har gjorts i Blazor projektmallar. Det går inte att lista varje ändring av mallarna i dokumentationen. Information om hur du migrerar en app till .NET 7 för att implementera alla ändringar finns i Migrera från ASP.NET Core 6.0 till 7.0.
Experimentell QuickGrid
komponent
Den nya QuickGrid
-komponenten ger en praktisk komponent för datarutnät för de vanligaste kraven och som referensarkitektur och prestandabaslinje för alla som skapar Blazor datarutnätkomponenter.
Mer information finns i ASP.NET Core Blazor komponentenQuickGrid.
Livedemo: QuickGrid för Blazor exempelapp
Förbättringar av virtualisering
Virtualiseringsförbättringar i .NET 7:
- Komponenten
Virtualize
stöder användning av själva dokumentet som rullningsrot, som ett alternativ till att använda något annat element medoverflow-y: scroll
. - Om
Virtualize
komponenten placeras i ett element som kräver ett specifikt underordnat taggnamn kan duSpacerElement
hämta eller ange namnet på virtualiseringsavståndstaggen.
Mer information finns i följande avsnitt i artikeln Virtualisering:
MouseEventArgs
uppdateringar
MovementX
och MovementY
har lagts till i MouseEventArgs
.
Mer information finns i ASP.NET Core Blazor händelsehantering.
Ny Blazor inläsningssida
Blazor WebAssembly-projektmallen har ett nytt inläsningsgränssnitt som visar förloppet för inläsning av appen.
Mer information finns i ASP.NET Core Blazor start.
Förbättrad diagnostik för autentisering i Blazor WebAssembly
För att diagnostisera autentiseringsproblem i Blazor WebAssembly appar är detaljerad loggning tillgänglig.
Mer information finns i ASP.NET Core Blazor loggning.
JavaScript-interoperabilitet med WebAssembly
JavaScript [JSImport]
/[JSExport]
interop API är en ny lågnivåmekanism för användning av .NET i Blazor WebAssembly- och JavaScript-baserade appar. Med den här nya JavaScript-interopfunktionen kan du anropa .NET-kod från JavaScript med hjälp av .NET WebAssembly-körningen och anropa JavaScript-funktioner från .NET utan något beroende av komponentmodellen Blazor UI.
Mer information finns i:
- JavaScript JSImport/JSExport interop med ASP.NET Core Blazor: Gäller endast för Blazor WebAssembly appar.
- JavaScript [JSImport]'/'[JSExport]' interop i .NET WebAssembly: Avser endast JavaScript-appar som inte är beroende av komponentmodellen Blazor UI.
Villkorsstyrd registrering av autentiseringstillståndsprovidern
Innan .NET 7 släpptes registrerades AuthenticationStateProvider
i tjänstcontainern med AddScoped
. Detta gjorde det svårt att felsöka appar eftersom det tvingade fram en viss ordning för tjänstregistreringar när en anpassad implementering tillhandahölls. På grund av interna ramverksändringar över tid behöver du inte längre registrera AuthenticationStateProvider
med AddScoped
.
I utvecklarkod gör du följande ändring av tjänstregistreringen för autentiseringstillståndsprovidern:
- builder.Services.AddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
+ builder.Services.TryAddScoped<AuthenticationStateProvider, ExternalAuthStateProvider>();
I föregående exempel är ExternalAuthStateProvider
utvecklarens tjänstimplementering.
Förbättringar av .NET WebAssembly-byggverktygen
Nya funktioner i arbetsbelastningen wasm-tools
för .NET 7 som hjälper till att förbättra prestanda och hantera undantag:
- WebAssembly Single Instruction stöd för flera data (SIMD) (endast med AOT, stöds inte av Apple Safari)
- Stöd för webassembly-undantagshantering
Mer information finns i ASP.NET Core Blazor WebAssembly byggverktyg och ahead-of-time (AOT) kompilering.
Blazor Hybrid
Externa URL:er
Ett alternativ har lagts till som tillåter att externa webbsidor öppnas i webbläsaren.
Mer information finns i ASP.NET Core Blazor Hybrid routning och navigering.
Säkerhet
Det finns ny vägledning för Blazor Hybrid säkerhetsscenarier. Mer information finns i följande artiklar:
- ASP.NET Core Blazor Hybrid-autentisering och auktorisering
- ASP.NET Core Blazor Hybrid säkerhetsöverväganden
Prestanda
Mellanprogram för cachelagring av utdata
Cachelagring av utdata är ett nytt mellanprogram som lagrar svar från en webbapp och hanterar dem från en cache i stället för att beräkna dem varje gång. Cachelagring av utdata skiljer sig från cachelagring av svar på följande sätt:
- Cachelagringsbeteendet kan konfigureras på servern.
- Cacheposter kan programmatiskt ogiltigförklaras.
- Resurslåsning minskar risken för cache-anstormning och tordönsflock.
- Cachevalidering innebär att servern kan returnera en
304 Not Modified
HTTP-statuskod istället för ett cachelagrat svarsinnehåll. - Cachelagringsmediet är utökningsbart.
Mer information finns i Cacheöversikt och Mellanprogram för cachelagring av utdata.
HTTP/3-förbättringar
Den här versionen:
- Säkerställer att HTTP/3 stöds fullt ut av ASP.NET Core och att det inte längre är experimentellt.
- Förbättrar Kestrelstöd för HTTP/3. De två viktigaste förbättringsområdena är funktionsparitet med HTTP/1.1 och HTTP/2 samt prestanda.
- Ger fullständigt stöd för UseHttps(ListenOptions, X509Certificate2) med HTTP/3. Kestrel erbjuder avancerade alternativ för att konfigurera anslutningscertifikat, till exempel att ansluta till SNI (Server Name Indication).
- Lägger till stöd för HTTP/3 på HTTP.sys och IIS-.
I följande exempel visas hur du använder ett SNI-återanrop för att lösa TLS-alternativ:
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);
},
});
});
});
Betydande arbete utfördes i .NET 7 för att minska HTTP/3-allokeringar. Du kan se några av dessa förbättringar i följande GitHub PR:er:
- HTTP/3: Undvik allokeringar av annulleringstoken per begäran
- HTTP/3: Undvik allokeringar av ConnectionAbortedException
- HTTP/3: ValueTask-poolning
Prestandaförbättringar för HTTP/2
.NET 7 introducerar en betydande omarkitektur för hur Kestrel bearbetar HTTP/2-begäranden. ASP.NET Core-appar med upptagna HTTP/2-anslutningar får minskad CPU-användning och högre dataflöde.
Tidigare förlitade sig HTTP/2-multiplexingimplementeringen på ett lås för att styra vilken begäran som kan skriva till den underliggande TCP-anslutningen. En trådsäker kö ersätter skrivlåset. Nu, i stället för att slåss om vilken tråd som får använda skrivlåset, köar begäranden nu och en dedikerad konsument bearbetar dem. Tidigare bortkastade CPU-resurser är tillgängliga för resten av appen.
En plats där dessa förbättringar kan märkas finns i gRPC, ett populärt RPC-ramverk som använder HTTP/2. Kestrel + gRPC benchmarks visar en dramatisk förbättring:
Ändringar har gjorts i HTTP/2-ramens skrivkod som förbättrar prestandan när det finns flera strömmar som försöker skriva data på en enda HTTP/2-anslutning. Vi skickar nu TLS-arbete till trådpoolen och frigör snabbare ett skrivlås som andra strömmar kan tillgå för att skriva sin data. Den minskade väntetiden kan ge betydande prestandaförbättringar i fall där det råder konkurrens om det här skrivlåset. Ett gRPC-prestandatest med 70 strömmar på en enda anslutning (med TLS) visade en förbättring på cirka 15 %% i förfrågningar per sekund (RPS) med denna förändring.
Stöd för Http/2 WebSockets
.NET 7 introducerar WebSockets via HTTP/2-stöd för Kestrel, SignalR JavaScript-klienten och SignalR med Blazor WebAssembly.
Användning av WebSockets via HTTP/2 drar nytta av nya funktioner som:
- Rubrikkomprimering.
- Multiplexering, vilket minskar den tid och de resurser som behövs när du gör flera begäranden till servern.
Dessa funktioner som stöds är tillgängliga i Kestrel på alla HTTP/2-aktiverade plattformar. Versionsförhandlingen sker automatiskt i webbläsare och Kestrel, så inga nya API:er behövs.
Mer information finns i Http/2 WebSockets support.
Kestrel prestandaförbättringar på högkärnig datorer
Kestrel använder ConcurrentQueue<T> i många syften. Ett syfte är att schemalägga I/O-åtgärder i Kestrel:s standardtransport för Socket. Partitionering av ConcurrentQueue
baserat på den associerade socketen minskar konkurrensen och ökar dataflödet på datorer med många CPU-kärnor.
Profilering på högkärniga datorer på .NET 6 visade betydande låsning i en av Kestrel:s andra ConcurrentQueue
-instanser, PinnedMemoryPool
som Kestrel använder för att cachelagra bytebuffertar.
I .NET 7 partitioneras Kestrelminnespool på samma sätt som dess I/O-kö, vilket leder till mycket lägre konkurrens och högre dataflöde på datorer med hög kärna. På ARM64 VMs med 80 kärnor ser vi en förbättring på över 500% i svar per sekund (RPS) i TechEmpower's benchmark för klartext. På 48-kärniga AMD-virtuella maskiner är förbättringen nästan 100% för vårt HTTPS JSON-riktmärke.
ServerReady
händelse för att mäta starttiden
Appar som använder EventSource kan mäta starttiden för att förstå och optimera startprestanda. Den nya ServerReady
händelsen i Microsoft.AspNetCore.Hosting representerar den punkt där servern är redo att svara på begäranden.
Server
Ny ServerReady-händelse för att mäta starttiden
Händelsen ServerReady
har lagts till som mäter starttid för ASP.NET Core-appar.
IIS
Skuggkopiering i IIS
Skuggkopiering av appsammansättningar till ASP.NET Core Module (ANCM) för IIS kan ge en bättre slutanvändarupplevelse än att stoppa appen genom att distribuera en offlinefil för app.
Mer information finns i Skuggkopiering i IIS.
Diverse
Kestrel fullständiga förbättringar av certifikatkedjan
HttpsConnectionAdapterOptions har en ny ServerCertificateChain egenskap av typen X509Certificate2Collection, vilket gör det enklare att verifiera certifikatkedjor genom att tillåta att en fullständig kedja med mellanliggande certifikat anges. Mer information finns i dotnet/aspnetcore#21513.
dotnet watch
Förbättrade konsolutdata för dotnet watch
Konsolutdata från dotnet watch har förbättrats för att bättre överensstämma med loggningen av ASP.NET Core och för att sticka ut med 😮emojis😍.
Här är ett exempel på hur de nya utdata ser ut:
Mer information finns i denna pull request på GitHub.
Konfigurera dotnet watch för att alltid starta om för oförskämda redigeringar
Oförskämda redigeringar är redigeringar som inte kan läsas in på nytt. Om du vill konfigurera dotnet watch för att alltid starta om utan en uppmaning om oförskämda redigeringar anger du DOTNET_WATCH_RESTART_ON_RUDE_EDIT
miljövariabeln till true
.
Mörkt läge för undantagssida för utvecklare
Stöd för mörkt läge har lagts till på undantagssidan för utvecklare tack vare ett bidrag från Patrick Westerhoff. Om du vill testa mörkt läge i en webbläsare från sidan med utvecklarverktyg anger du läget till mörkt. Till exempel i Firefox:
I Chrome:
Projektmallsalternativ för att använda Program.Main-metoden i stället för toppnivåinstruktioner
.NET 7-mallarna innehåller ett alternativ att inte använda toppnivåinstruktioner, och generera en namespace
-metod och en Main
-metod som deklarerats i en Program
-klass.
Använd alternativet --use-program-main
med .NET CLI:
dotnet new web --use-program-main
I Visual Studio väljer du kryssrutan Nya Använd inte instruktioner på den översta nivån när du skapar ett projekt:
kryssrutan
Angular- och React-mallar har uppdaterats
Angular-projektmallen har uppdaterats till Angular 14. React-projektmallen har uppdaterats till React 18.2.
Hantera JSON-webbtoken under utveckling med dotnet user-jwts
Det nya dotnet user-jwts
kommandoradsverktyget kan skapa och hantera appspecifika lokala JSON-webbtoken (JWT). Mer information finns i Hantera JSON-webbtoken under utveckling med dotnet user-jwts.
Stöd för ytterligare begärandehuvuden i W3CLogger
Du kan nu ange ytterligare begärandehuvuden som ska loggas när du använder W3C-loggaren genom att anropa AdditionalRequestHeaders()
på W3CLoggerOptions:
services.AddW3CLogging(logging =>
{
logging.AdditionalRequestHeaders.Add("x-forwarded-for");
logging.AdditionalRequestHeaders.Add("x-client-ssl-protocol");
});
Mer information finns i W3CLogger-alternativ.
Begär dekomprimering
Det nya Request decompression middleware:
- Gör att API-slutpunkter kan acceptera begäranden med komprimerat innehåll.
- Använder
Content-Encoding
HTTP-huvud för att automatiskt identifiera och dekomprimera begäranden som innehåller komprimerat innehåll. - Eliminerar behovet av att skriva kod för att hantera komprimerade begäranden.
Mer information finns i Request decompression middleware.
ASP.NET Core