gebeurtenis
Power BI DataViz World Championships
14 feb, 16 - 31 mrt, 16
Met 4 kansen om in te gaan, kun je een conferentiepakket winnen en het naar de LIVE Grand Finale in Las Vegas maken
Meer informatieDeze browser wordt niet meer ondersteund.
Upgrade naar Microsoft Edge om te profiteren van de nieuwste functies, beveiligingsupdates en technische ondersteuning.
Notitie
Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.
Waarschuwing
Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.
Belangrijk
Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.
Zie de .NET 9-versie van dit artikelvoor de huidige release.
Door Mike Rousos
Dit artikel bevat richtlijnen voor het maximaliseren van prestaties en betrouwbaarheid van ASP.NET Core-apps.
Caching wordt in verschillende delen van dit artikel besproken. Zie Overzicht van caching in ASP.NET Corevoor meer informatie.
In dit artikel wordt een hotcodepad gedefinieerd als een codepad dat vaak wordt aangeroepen en waar veel van de uitvoeringstijd plaatsvindt. Hot codepaden beperken typisch de schaalbaarheid en de prestaties van apps en worden in verschillende delen van dit artikel besproken.
ASP.NET Core-apps moeten zijn ontworpen om veel aanvragen tegelijkertijd te verwerken. Met asynchrone API's kan een kleine groep threads duizenden gelijktijdige aanvragen verwerken door niet te wachten op blokkeringsaanroepen. In plaats van te wachten op een langlopende synchrone taak om te voltooien, kan de thread aan een andere aanvraag werken.
Een veelvoorkomend prestatieprobleem in ASP.NET Core-apps blokkeert aanroepen die asynchroon kunnen zijn. Veel synchrone blokkade-aanroepen leiden tot Thread Pool-uitputting en verslechterde reactietijden.
asynchrone uitvoering niet blokkeren door Task.Wait of Task<TResult>.Resultaan te roepen.
Verwerf geen vergrendelingen in veelgebruikte codepaden. ASP.NET Core-apps presteren het beste wanneer u code parallel wilt uitvoeren.
Bel Task.Run niet en wacht er onmiddellijk op. ASP.NET Core voert al applicatiecode uit op normale Thread Pool-threads, waardoor het aanroepen van Task.Run
alleen resulteert in extra en onnodige scheduling van de Thread Pool. Zelfs als de geplande code een thread blokkeert, voorkomt Task.Run
dat niet.
Een profiler, zoals PerfView-, kan worden gebruikt om threads te vinden die vaak worden toegevoegd aan de Thread-pool. De Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start
gebeurtenis geeft een thread aan die is toegevoegd aan de threadgroep.
Een webpagina mag niet grote hoeveelheden gegevens tegelijk laden. Wanneer u een verzameling objecten retourneert, kunt u overwegen of dit kan leiden tot prestatieproblemen. Bepaal of het ontwerp de volgende slechte resultaten kan opleveren:
Voeg paginering toe om de impact van de voorgaande scenario's te verminderen. Met behulp van parameters voor paginaformaat en paginaindex moeten ontwikkelaars de voorkeur geven aan het ontwerp van het retourneren van een gedeeltelijk resultaat. Wanneer een volledig resultaat vereist is, moet paginering worden gebruikt om asynchroon batches met resultaten te vullen om te voorkomen dat serverbronnen worden vergrendeld.
Zie voor meer informatie over paging en het beperken van het aantal geretourneerde records:
Het retourneren van IEnumerable<T>
van een actie resulteert in synchrone verzamelingsiteratie door de serializer. Het resultaat is de blokkering van aanroepen en een potentieel voor threadpool-uitputting. Als u synchrone opsomming wilt voorkomen, gebruikt u ToListAsync
voordat u de opsomming retourneert.
Vanaf ASP.NET Core 3.0 kan IAsyncEnumerable<T>
worden gebruikt als alternatief voor IEnumerable<T>
die asynchroon opsommen. Zie voor meer informatie controlleractie-retourtypen.
De .NET Core garbage collector beheert de toewijzing en het vrijgeven van geheugen automatisch in ASP.NET Core-apps. Automatische geheugenbeheer betekent over het algemeen dat ontwikkelaars zich geen zorgen hoeven te maken over hoe of wanneer geheugen wordt vrijgemaakt. Het opschonen van niet-gereferentieerde objecten kost echter CPU-tijd, dus ontwikkelaars moeten het toewijzen van objecten in hot code pathsminimaliseren. Garbagecollection is vooral duur voor grote objecten (>= 85.000 bytes). Grote objecten worden opgeslagen op de grote object heap en vereisen een volledige (generatie 2) garbagecollection om op te schonen. In tegenstelling tot verzamelingen van generatie 0 en generatie 1 is voor een verzameling van de tweede generatie een tijdelijke schorsing van de uitvoering van apps vereist. Frequente toewijzing en onttoewijzing van grote objecten kunnen inconsistente prestaties veroorzaken.
Aanbevelingen:
Geheugenproblemen, zoals de voorgaande, kunnen worden gediagnosticeerd door de statistieken van de garbage collection (GC) in PerfView te bekijken en te analyseren.
Voor meer informatie, zie Vuilnisophaling en Prestaties.
Interacties met een gegevensarchief en andere externe services zijn vaak de traagste onderdelen van een ASP.NET Core-app. Het efficiënt lezen en schrijven van gegevens is essentieel voor goede prestaties.
Aanbevelingen:
.Where
-, .Select
- of .Sum
-uitdrukkingen) zodat het filteren wordt uitgevoerd door de database.De volgende benaderingen kunnen de prestaties in apps op grote schaal verbeteren:
We raden u aan de impact van de voorgaande high-performance benaderingen te meten voordat u de codebasis doorvoert. De extra complexiteit van gecompileerde query's rechtvaardigt mogelijk niet de prestatieverbetering.
Queryproblemen kunnen worden gedetecteerd door de tijd te bekijken die nodig is om toegang te krijgen tot gegevens met Application Insights- of met profileringshulpprogramma's. De meeste databases maken ook statistieken beschikbaar met betrekking tot vaak uitgevoerde query's.
Hoewel HttpClient de IDisposable
-interface implementeert, is deze ontworpen voor hergebruik. Gesloten HttpClient
instellingen laten sockets voor een korte periode open in de status TIME_WAIT
. Als een codepad dat HttpClient
objecten maakt en verwijdert vaak wordt gebruikt, kan de app beschikbare sockets uitputten.
HttpClientFactory
werd geïntroduceerd in ASP.NET Core 2.1 als oplossing voor dit probleem. Het verwerkt het groeperen van HTTP-verbindingen om de prestaties en betrouwbaarheid te optimaliseren. Zie Gebruik HttpClientFactory
voor het implementeren van tolerante HTTP-aanvragenvoor meer informatie.
Aanbevelingen:
HttpClient
instanties rechtstreeks.HttpClient
instanties op te halen. Zie HttpClientFactory gebruiken om tolerante HTTP-aanvragen te implementerenvoor meer informatie.U wilt dat al uw code snel is. Veelgebruikte codepaden zijn het meest essentieel om te optimaliseren. Dit zijn onder andere:
Aanbevelingen:
De meeste aanvragen voor een ASP.NET Core-app kunnen worden verwerkt door een controller of paginamodel dat de benodigde services aanroept en een HTTP-antwoord retourneert. Voor sommige aanvragen die betrekking hebben op langlopende taken, is het beter om het hele proces voor aanvraagrespons asynchroon te maken.
Aanbevelingen:
ASP.NET Core-apps met complexe front-ends dienen vaak veel JavaScript-, CSS- of afbeeldingsbestanden. De prestaties van initiële belastingsaanvragen kunnen worden verbeterd door:
Aanbevelingen:
environment
tag van ASP.NET Core kunt gebruiken om zowel Development
als Production
omgevingen te verwerken.Door de grootte van het antwoord te verkleinen, wordt de reactiesnelheid van een app meestal aanzienlijk verhoogd. Een manier om nettoladinggrootten te verminderen, is door de reacties van een app te comprimeren. Voor meer informatie, zie Antwoordcompressie.
Elke nieuwe release van ASP.NET Core bevat prestatieverbeteringen. Optimalisaties in .NET Core en ASP.NET Core betekenen dat nieuwere versies over het algemeen beter presteren dan oudere versies. .NET Core 2.1 heeft bijvoorbeeld ondersteuning toegevoegd voor gecompileerde reguliere expressies en baat gehad bij Span<T->. ASP.NET Core 2.2 heeft ondersteuning toegevoegd voor HTTP/2. ASP.NET Core 3.0 voegt veel verbeteringen toe die het geheugengebruik verminderen en de doorvoer verbeteren. Als de prestaties een prioriteit hebben, kunt u overwegen om een upgrade uit te voeren naar de huidige versie van ASP.NET Core.
Uitzonderingen moeten zeldzaam zijn. Het genereren en vangen van uitzonderingen is traag ten opzichte van andere codestroompatronen. Daarom mogen uitzonderingen niet worden gebruikt om de normale programmastroom te beheren.
Aanbevelingen:
Diagnostische hulpprogramma's voor apps, zoals Application Insights, kunnen helpen bij het identificeren van veelvoorkomende uitzonderingen in een app die van invloed kunnen zijn op de prestaties.
Alle I/O in ASP.NET Core is asynchroon. Servers implementeren de Stream
interface, die zowel synchrone als asynchrone overbelastingen heeft. De asynchrone threads moeten de voorkeur hebben om blokkering van threadpoolthreads te voorkomen. Het blokkeren van threads kan leiden tot starvatie van threadgroepen.
Doe dit niet: In het volgende voorbeeld wordt de ReadToEndgebruikt. De huidige thread wordt geblokkeerd om te wachten op het resultaat. Dit is een voorbeeld van synchronisatie via asynchrone.
public class BadStreamReaderController : Controller
{
[HttpGet("/contoso")]
public ActionResult<ContosoData> Get()
{
var json = new StreamReader(Request.Body).ReadToEnd();
return JsonSerializer.Deserialize<ContosoData>(json);
}
}
In de voorgaande code leest Get
synchroon de volledige HOOFDtekst van de HTTP-aanvraag in het geheugen. Als de client langzaam uploadt, doet de app synchronisatie via asynchroon. De app wordt gesynchroniseerd via asynchroon omdat KestrelNIET synchrone leesbewerkingen ondersteunt.
Dit doet u: In het volgende voorbeeld wordt ReadToEndAsync gebruikt en wordt de thread niet geblokkeerd tijdens het lezen.
public class GoodStreamReaderController : Controller
{
[HttpGet("/contoso")]
public async Task<ActionResult<ContosoData>> Get()
{
var json = await new StreamReader(Request.Body).ReadToEndAsync();
return JsonSerializer.Deserialize<ContosoData>(json);
}
}
De voorgaande code leest asynchroon de volledige HOOFDtekst van de HTTP-aanvraag in het geheugen.
Waarschuwing
Als de aanvraag groot is, kan het lezen van de volledige HTTP-aanvraagbody in het geheugen leiden tot een OOM-voorwaarde (onvoldoende geheugen). OOM kan resulteren in een Denial Of Service. Zie Vermijd het lezen van grote aanvraagteksten of antwoordteksten in het geheugen in dit artikel voor meer informatie.
Dit doet u: Het volgende voorbeeld is volledig asynchroon met behulp van een niet-gebufferde aanvraagbody:
public class GoodStreamReaderController : Controller
{
[HttpGet("/contoso")]
public async Task<ActionResult<ContosoData>> Get()
{
return await JsonSerializer.DeserializeAsync<ContosoData>(Request.Body);
}
}
Met de voorgaande code wordt de aanvraagbody asynchroon gedeserialiseerd in een C#-object.
Gebruik HttpContext.Request.ReadFormAsync
in plaats van HttpContext.Request.Form
.
HttpContext.Request.Form
kan alleen veilig worden gelezen onder de volgende voorwaarden:
ReadFormAsync
enHttpContext.Request.Form
Doe dit niet: In het volgende voorbeeld wordt HttpContext.Request.Form
gebruikt.
HttpContext.Request.Form
gebruikt synchronisatie over asynchroon en kan leiden tot uitputting van de threadpool.
public class BadReadController : Controller
{
[HttpPost("/form-body")]
public IActionResult Post()
{
var form = HttpContext.Request.Form;
Process(form["id"], form["name"]);
return Accepted();
}
Dit doet u: In het volgende voorbeeld wordt HttpContext.Request.ReadFormAsync
gebruikt om de hoofdtekst van het formulier asynchroon te lezen.
public class GoodReadController : Controller
{
[HttpPost("/form-body")]
public async Task<IActionResult> Post()
{
var form = await HttpContext.Request.ReadFormAsync();
Process(form["id"], form["name"]);
return Accepted();
}
In .NET komt elke objecttoewijzing groter dan of gelijk aan 85.000 bytes in de grote object heap (LOH). Grote objecten zijn op twee manieren duur:
In dit blogbericht wordt het probleem beknopt beschreven:
Wanneer een groot object wordt toegewezen, wordt het gemarkeerd als Gen 2-object. Niet Gen 0 voor kleine objecten. De gevolgen zijn dat als je een geheugen tekort in LOH hebt, GC de hele beheerde heap opschoont, niet alleen LOH. Dus het schoont Gen 0, Gen 1 en Gen 2 inclusief LOH op. Dit wordt een volledige vuilopruiming genoemd en is de meest tijdrovende vuilopruiming. Voor veel toepassingen kan het acceptabel zijn. Maar zeker niet voor krachtige webservers, waarbij er weinig grote geheugenbuffers nodig zijn om een gemiddelde webaanvraag af te handelen (lezen uit een socket, decomprimeren, JSON decoderen en meer).
Het opslaan van een grote aanvraag- of antwoordtekst in één byte[]
of string
:
Wanneer u een serializer/de-serializer gebruikt die alleen synchrone lees- en schrijfbewerkingen ondersteunt (bijvoorbeeld Json.NET):
Waarschuwing
Als de aanvraag groot is, kan dit leiden tot een out of memory (onvoldoende geheugen) situatie. OOM kan resulteren in een Denial Of Service. Zie Vermijd het lezen van grote aanvraagteksten of antwoordteksten in het geheugen in dit artikel voor meer informatie.
ASP.NET Core 3.0 gebruikt standaard System.Text.Json voor JSON-serialisatie. System.Text.Json:
Newtonsoft.Json
.De IHttpContextAccessor.HttpContext retourneert de HttpContext
van de actieve aanvraag wanneer deze wordt geopend vanuit de aanvraagthread. De IHttpContextAccessor.HttpContext
mag niet in een veld of variabele worden opgeslagen.
Doe dit niet: In het volgende voorbeeld wordt de HttpContext
opgeslagen in een veld en wordt vervolgens later geprobeerd deze te gebruiken.
public class MyBadType
{
private readonly HttpContext _context;
public MyBadType(IHttpContextAccessor accessor)
{
_context = accessor.HttpContext;
}
public void CheckAdmin()
{
if (!_context.User.IsInRole("admin"))
{
throw new UnauthorizedAccessException("The current user isn't an admin");
}
}
}
De voorgaande code legt vaak een null- of onjuiste HttpContext
vast in de constructor.
Ga als volgt te werk: Het volgende voorbeeld:
HttpContext
veld op het juiste tijdstip en controleert op null
.public class MyGoodType
{
private readonly IHttpContextAccessor _accessor;
public MyGoodType(IHttpContextAccessor accessor)
{
_accessor = accessor;
}
public void CheckAdmin()
{
var context = _accessor.HttpContext;
if (context != null && !context.User.IsInRole("admin"))
{
throw new UnauthorizedAccessException("The current user isn't an admin");
}
}
}
HttpContext
is niet threadveilig. Toegang tot HttpContext
vanuit meerdere threads parallel kan leiden tot onverwacht gedrag, zoals de server om te stoppen met reageren, crashes en beschadiging van gegevens.
Doe dit niet: In het volgende voorbeeld worden drie parallelle aanvragen uitgevoerd en wordt het binnenkomende aanvraagpad vóór en na de uitgaande HTTP-aanvraag in een logboek opgeslagen. Het aanvraagpad wordt geopend vanuit meerdere threads, mogelijk parallel.
public class AsyncBadSearchController : Controller
{
[HttpGet("/search")]
public async Task<SearchResults> Get(string query)
{
var query1 = SearchAsync(SearchEngine.Google, query);
var query2 = SearchAsync(SearchEngine.Bing, query);
var query3 = SearchAsync(SearchEngine.DuckDuckGo, query);
await Task.WhenAll(query1, query2, query3);
var results1 = await query1;
var results2 = await query2;
var results3 = await query3;
return SearchResults.Combine(results1, results2, results3);
}
private async Task<SearchResults> SearchAsync(SearchEngine engine, string query)
{
var searchResults = _searchService.Empty();
try
{
_logger.LogInformation("Starting search query from {path}.",
HttpContext.Request.Path);
searchResults = _searchService.Search(engine, query);
_logger.LogInformation("Finishing search query from {path}.",
HttpContext.Request.Path);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed query from {path}",
HttpContext.Request.Path);
}
return await searchResults;
}
Dit doet u: In het volgende voorbeeld worden alle gegevens uit de binnenkomende aanvraag gekopieerd voordat u de drie parallelle aanvragen maakt.
public class AsyncGoodSearchController : Controller
{
[HttpGet("/search")]
public async Task<SearchResults> Get(string query)
{
string path = HttpContext.Request.Path;
var query1 = SearchAsync(SearchEngine.Google, query,
path);
var query2 = SearchAsync(SearchEngine.Bing, query, path);
var query3 = SearchAsync(SearchEngine.DuckDuckGo, query, path);
await Task.WhenAll(query1, query2, query3);
var results1 = await query1;
var results2 = await query2;
var results3 = await query3;
return SearchResults.Combine(results1, results2, results3);
}
private async Task<SearchResults> SearchAsync(SearchEngine engine, string query,
string path)
{
var searchResults = _searchService.Empty();
try
{
_logger.LogInformation("Starting search query from {path}.",
path);
searchResults = await _searchService.SearchAsync(engine, query);
_logger.LogInformation("Finishing search query from {path}.", path);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed query from {path}", path);
}
return await searchResults;
}
HttpContext
is alleen geldig zolang er een actieve HTTP-aanvraag is in de ASP.NET Core-pijplijn. De volledige ASP.NET Core-pijplijn is een asynchrone keten van gemachtigden die elke aanvraag uitvoeren. Wanneer de Task
uit deze keten terugkeert en is voltooid, wordt de HttpContext
gerecycled.
Doe dit niet: in het volgende voorbeeld wordt async void
gebruikt, waardoor de HTTP-aanvraag is voltooid wanneer de eerste await
is bereikt:
async void
is ALTIJD een slechte praktijk in ASP.NET Core-applicaties.HttpResponse
nadat de HTTP-aanvraag is voltooid.public class AsyncBadVoidController : Controller
{
[HttpGet("/async")]
public async void Get()
{
await Task.Delay(1000);
// The following line will crash the process because of writing after the
// response has completed on a background thread. Notice async void Get()
await Response.WriteAsync("Hello World");
}
}
Dit doet u: Het volgende voorbeeld retourneert een Task
naar het framework, zodat de HTTP-aanvraag pas wordt voltooid als de actie is voltooid.
public class AsyncGoodTaskController : Controller
{
[HttpGet("/async")]
public async Task Get()
{
await Task.Delay(1000);
await Response.WriteAsync("Hello World");
}
}
Doe dit niet: Het volgende voorbeeld laat zien dat een closure de HttpContext
van de eigenschap Controller
vastlegt. Dit is een slechte gewoonte omdat het werkitem het volgende kan doen:
HttpContext
te lezen.[HttpGet("/fire-and-forget-1")]
public IActionResult BadFireAndForget()
{
_ = Task.Run(async () =>
{
await Task.Delay(1000);
var path = HttpContext.Request.Path;
Log(path);
});
return Accepted();
}
Doe dit: Het volgende voorbeeld:
[HttpGet("/fire-and-forget-3")]
public IActionResult GoodFireAndForget()
{
string path = HttpContext.Request.Path;
_ = Task.Run(async () =>
{
await Task.Delay(1000);
Log(path);
});
return Accepted();
}
Achtergrondtaken moeten worden geïmplementeerd als gehoste services. Zie Achtergrondtaken met gehoste servicesvoor meer informatie.
Doe dit niet: In het volgende voorbeeld ziet u een closure die de DbContext
vastlegt vanuit de actieparameter Controller
. Dit is een slechte gewoonte. Het werkitem kan buiten het aanvraagbereik worden uitgevoerd. De ContosoDbContext
is beperkt tot de aanvraag, wat resulteert in een ObjectDisposedException
.
[HttpGet("/fire-and-forget-1")]
public IActionResult FireAndForget1([FromServices]ContosoDbContext context)
{
_ = Task.Run(async () =>
{
await Task.Delay(1000);
context.Contoso.Add(new Contoso());
await context.SaveChangesAsync();
});
return Accepted();
}
Doe dit: Het volgende voorbeeld:
IServiceScopeFactory
is een singleton.ContosoDbContext
niet vast van de binnenkomende aanvraag.[HttpGet("/fire-and-forget-3")]
public IActionResult FireAndForget3([FromServices]IServiceScopeFactory
serviceScopeFactory)
{
_ = Task.Run(async () =>
{
await Task.Delay(1000);
await using (var scope = serviceScopeFactory.CreateAsyncScope())
{
var context = scope.ServiceProvider.GetRequiredService<ContosoDbContext>();
context.Contoso.Add(new Contoso());
await context.SaveChangesAsync();
}
});
return Accepted();
}
De volgende gemarkeerde code:
ContosoDbContext
uit het juiste bereik.[HttpGet("/fire-and-forget-3")]
public IActionResult FireAndForget3([FromServices]IServiceScopeFactory
serviceScopeFactory)
{
_ = Task.Run(async () =>
{
await Task.Delay(1000);
await using (var scope = serviceScopeFactory.CreateAsyncScope())
{
var context = scope.ServiceProvider.GetRequiredService<ContosoDbContext>();
context.Contoso.Add(new Contoso());
await context.SaveChangesAsync();
}
});
return Accepted();
}
ASP.NET Core buffert de hoofdtekst van het HTTP-antwoord niet. De eerste keer dat het antwoord wordt geschreven:
Doe dit niet: De volgende code probeert antwoordheaders toe te voegen nadat het antwoord al is gestart:
app.Use(async (context, next) =>
{
await next();
context.Response.Headers["test"] = "test value";
});
In de voorgaande code genereert context.Response.Headers["test"] = "test value";
een uitzondering als next()
naar het antwoord heeft geschreven.
Dit doet u: In het volgende voorbeeld wordt gecontroleerd of het HTTP-antwoord is gestart voordat u de headers wijzigt.
app.Use(async (context, next) =>
{
await next();
if (!context.Response.HasStarted)
{
context.Response.Headers["test"] = "test value";
}
});
Dit doet u: In het volgende voorbeeld wordt HttpResponse.OnStarting
gebruikt om de headers in te stellen voordat de antwoordheaders naar de client worden leeggemaakt.
Door te controleren of de respons nog niet is gestart, wordt het mogelijk om een callback te registreren die net voordat de responsheaders worden geschreven, wordt opgeroepen. Controleren of de reactie nog niet is begonnen:
app.Use(async (context, next) =>
{
context.Response.OnStarting(() =>
{
context.Response.Headers["someheader"] = "somevalue";
return Task.CompletedTask;
});
await next();
});
Onderdelen verwachten alleen te worden aangeroepen als ze het antwoord kunnen verwerken en manipuleren.
Met in-process hosting wordt een ASP.NET Core-app uitgevoerd in hetzelfde proces als het IIS-werkproces. In-process hosting biedt verbeterde prestaties ten opzichte van out-of-process hosting, omdat aanvragen niet worden geproxied via de loopback-adapter. De loopback-adapter is een netwerkinterface die uitgaand netwerkverkeer retourneert naar dezelfde computer. IIS verwerkt procesbeheer met de WAS-(Windows Process Activation Service).
Projecten zijn standaard ingesteld op het in-process hostingmodel in ASP.NET Core 3.0 en hoger.
Zie Host ASP.NET Core in Windows met IIS- voor meer informatie
HttpRequest.ContentLength
is null als de Content-Length
header niet wordt ontvangen. Null in dat geval betekent dat de lengte van de aanvraagbody niet bekend is; Het betekent niet dat de lengte nul is. Omdat alle vergelijkingen met null (behalve ==
) onwaar retourneren, kan de vergelijking Request.ContentLength > 1024
bijvoorbeeld false
retourneren wanneer de grootte van de aanvraagtekst groter is dan 1024. Als u dit niet weet, kan dit leiden tot beveiligingsgaten in apps. Misschien denkt u dat u zich beveiligt tegen te grote aanvragen als u dat niet doet.
Zie dit StackOverflow-antwoordvoor meer informatie.
Zie Enterprise-web-app-patronenvoor hulp bij het maken van een betrouwbare, veilige, uitvoerbare, testbare en schaalbare ASP.NET Core-app. Er is een volledige voorbeeldweb-app van productiekwaliteit beschikbaar waarmee de patronen worden geïmplementeerd.
ASP.NET Core-feedback
ASP.NET Core is een open source project. Selecteer een koppeling om feedback te geven:
gebeurtenis
Power BI DataViz World Championships
14 feb, 16 - 31 mrt, 16
Met 4 kansen om in te gaan, kun je een conferentiepakket winnen en het naar de LIVE Grand Finale in Las Vegas maken
Meer informatieTraining
Leertraject
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization
Certificering
Bouw end-to-end-oplossingen in Microsoft Azure om Azure Functions te maken, web-apps te implementeren en te beheren, oplossingen te ontwikkelen die gebruikmaken van Azure Storage en meer.
Documentatie
Afhankelijkheidsinjectie in ASP.NET Core
Meer informatie over hoe ASP.NET Core afhankelijkheidsinjectie implementeert en hoe u deze kunt gebruiken.
Meer informatie over hoe de opstartklasse in ASP.NET Core services en de aanvraagpijplijn van de app configureert.
Meer informatie over ASP.NET Core middleware en de aanvraagpijplijn.