Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)
Web TippsUse custom web fonts in Google Sheets charts(08.09.2026 um 17:05 Uhr)
Web TippsIntroducing the new 1Password App for Google Chat(08.09.2026 um 18:02 Uhr)

🔧 Programmierung 🕛 vor 2 Monaten 11 Min Lesezeit
0

ASP.NET Core: Building High-Performance Web Applications and APIs

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




ASP.NET Core: Building High-Performance Web Applications and APIs



A practical guide to ASP.NET Core — the cross-platform framework for building REST APIs, MVC applications, and backend services on .NET, covering architecture, minimal APIs, middleware, performance, and modern patterns.









Table of Contents




  1. Introduction

  2. Architecture Overview

  3. Minimal APIs

  4. MVC and Controllers

  5. Middleware Pipeline

  6. Dependency Injection

  7. Configuration and Options

  8. Authentication and Authorization

  9. Performance Features

  10. Testing and Observability

  11. Quick Reference Table

  12. Conclusion









Introduction



ASP.NET Core is a free, open-source, cross-platform framework for building web apps, APIs, and backend services. It's a ground-up rewrite of the original ASP.NET, designed around three priorities:





  • Performance — it's consistently one of the fastest mainstream web frameworks in independent benchmarks (e.g., TechEmpower).


  • Modularity — you opt into only the middleware and services your app actually needs, instead of a fixed, heavyweight pipeline.


  • Cross-platform — runs identically on Windows, Linux, and macOS, and deploys to containers, serverless, or bare metal.



This guide covers the core building blocks you'll use in almost any ASP.NET Core project, from a five-line minimal API to a full MVC application with authentication and background services.









1. Architecture Overview



Every ASP.NET Core app starts from a unified entry point — Program.cs — using the minimal hosting model introduced in .NET 6.




CODE
var builder = WebApplication.CreateBuilder(args);

// Register services (dependency injection container)
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline (middleware)
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();






Two phases matter here:





  1. Service registration (builder.Services...) — declares what your app needs (DI container setup).


  2. Pipeline configuration (app.Use... / app.Map...) — declares what happens to each incoming request.



This single-file, top-level-statements style replaced the old Startup.cs + Program.cs split, cutting boilerplate significantly while keeping the same underlying concepts.









2. Minimal APIs



Introduced in .NET 6, minimal APIs let you build HTTP APIs without controllers, attributes, or a large amount of scaffolding — ideal for microservices, small services, and prototypes.






A basic minimal API






CODE
var app = builder.Build();

app.MapGet("/products/{id:int}", (int id, IProductRepository repo) =>
{
var product = repo.GetById(id);
return product is not null ? Results.Ok(product) : Results.NotFound();
});

app.MapPost("/products", (Product product, IProductRepository repo) =>
{
repo.Add(product);
return Results.Created($"/products/{product.Id}", product);
});

app.Run();






Route parameters, request bodies, and services are all bound automatically from the method signature — no [FromRoute]/[FromBody] attributes required in the common case (though they're available when binding is ambiguous).






Route groups (.NET 7+)



Group related endpoints, apply shared configuration (auth, versioning, tags) once:




CODE
var products = app.MapGroup("/products").WithTags("Products");

products.MapGet("/", (IProductRepository repo) => repo.GetAll());
products.MapGet("/{id:int}", (int id, IProductRepository repo) => repo.GetById(id));
products.MapPost("/", (Product p, IProductRepository repo) => repo.Add(p))
.RequireAuthorization();









Typed results (.NET 7+)



Results<T1, T2> gives you strongly-typed, OpenAPI-friendly return types instead of the untyped IResult:




CODE
app.MapGet("/products/{id}", Results<Ok<Product>, NotFound> (int id, IProductRepository repo) =>
{
var product = repo.GetById(id);
return product is not null
? TypedResults.Ok(product)
: TypedResults.NotFound();
});









When to choose minimal APIs vs. controllers

































Minimal APIs MVC Controllers
Best for Microservices, small APIs, high-throughput endpoints Larger apps, complex validation, filters, conventions
Boilerplate Very low Moderate (attributes, base class)
Startup performance Faster (less reflection) Slightly slower
Structure at scale Requires discipline (route groups, extension methods) Built-in via controllers/areas








3. MVC and Controllers



For larger applications, the Model-View-Controller pattern still provides useful structure — action filters, model binding conventions, and view rendering.






A typical API controller






CODE
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
private readonly IOrderService _orderService;

public OrdersController(IOrderService orderService) => _orderService = orderService;

[HttpGet("{id:int}")]
public async Task<ActionResult<OrderDto>> GetById(int id)
{
var order = await _orderService.GetByIdAsync(id);
return order is not null ? Ok(order) : NotFound();
}

[HttpPost]
public async Task<ActionResult<OrderDto>> Create(CreateOrderRequest request)
{
var order = await _orderService.CreateAsync(request);
return CreatedAtAction(nameof(GetById), new { id = order.Id }, order);
}
}






The [ApiController] attribute enables automatic model-state validation (400 responses on invalid input), binding source inference, and problem-details error responses — all without extra code.






Razor Pages and MVC Views



For server-rendered HTML, ASP.NET Core supports both Razor Pages (page-focused, one file per page) and traditional MVC views (controller + shared view folder):




CODE
// Razor Page handler (Pages/Products/Index.cshtml.cs)
public class IndexModel : PageModel
{
private readonly IProductRepository _repo;
public IndexModel(IProductRepository repo) => _repo = repo;

public IList<Product> Products { get; set; } = [];

public async Task OnGetAsync() => Products = await _repo.GetAllAsync();
}









CODE
@* Pages/Products/Index.cshtml *@
@model IndexModel
<ul>
@foreach (var product in Model.Products)
{
<li>@product.Name — @product.Price.ToString("C")</li>
}
</ul>









Blazor as an alternative UI model



For interactive UIs without hand-written JavaScript, Blazor (Server or WebAssembly) lets you write component-based UI in C# that runs either on the server over SignalR or directly in the browser via WebAssembly. It's a separate topic in its own right, but it plugs into the same ASP.NET Core hosting model.









4. Middleware Pipeline



Middleware is the heart of how ASP.NET Core processes requests: each piece of middleware can inspect, short-circuit, or pass along the request to the next one, forming a chain.






The pipeline as nested delegates






CODE
app.Use(async (context, next) =>
{
var stopwatch = Stopwatch.StartNew();
await next(context); // call the next middleware in the chain
stopwatch.Stop();
Console.WriteLine($"{context.Request.Path} took {stopwatch.ElapsedMilliseconds}ms");
});

app.UseExceptionHandler("/error");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();






Order matters. Authentication must run before authorization; exception handling should wrap almost everything; static files are usually served before routing kicks in for dynamic endpoints.






Writing custom middleware as a class






CODE
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestLoggingMiddleware> _logger;

public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}

public async Task InvokeAsync(HttpContext context)
{
_logger.LogInformation("Handling {Method} {Path}", context.Request.Method, context.Request.Path);
await _next(context);
_logger.LogInformation("Response: {StatusCode}", context.Response.StatusCode);
}
}

// registration
app.UseMiddleware<RequestLoggingMiddleware>();









Endpoint routing



Since ASP.NET Core 3.0, routing is decoupled from MVC — UseRouting() and UseEndpoints() (or the simplified Map* calls) let middleware run with full knowledge of which endpoint will ultimately handle the request, enabling things like endpoint-specific authorization policies.









5. Dependency Injection



ASP.NET Core has a built-in DI container — no third-party library required for the common cases.






Service lifetimes






CODE
builder.Services.AddSingleton<ICacheService, MemoryCacheService>(); // one instance for the app's lifetime
builder.Services.AddScoped<IOrderService, OrderService>(); // one instance per HTTP request
builder.Services.AddTransient<IEmailSender, SmtpEmailSender>(); // new instance every time it's requested































Lifetime Instance created Typical use
Singleton Once, shared everywhere Caches, configuration, thread-safe stateless services
Scoped Once per request
DbContext, per-request state
Transient Every injection Lightweight, stateless helpers





Constructor injection






CODE
public class OrderService : IOrderService
{
private readonly AppDbContext _db;
private readonly IEmailSender _emailSender;

public OrderService(AppDbContext db, IEmailSender emailSender)
{
_db = db;
_emailSender = emailSender;
}

public async Task<Order> CreateAsync(CreateOrderRequest request)
{
var order = new Order { /* ... */ };
_db.Orders.Add(order);
await _db.SaveChangesAsync();
await _emailSender.SendOrderConfirmationAsync(order);
return order;
}
}









Keyed services (.NET 8+)



Register multiple implementations of the same interface and resolve by key:




CODE
builder.Services.AddKeyedSingleton<INotifier, EmailNotifier>("email");
builder.Services.AddKeyedSingleton<INotifier, SmsNotifier>("sms");

public class AlertService([FromKeyedServices("sms")] INotifier notifier) { /* ... */ }












6. Configuration and Options



Configuration in ASP.NET Core is layered: appsettings.json, environment-specific overrides, environment variables, and command-line args all merge together automatically.






appsettings.json






CODE
{
"ConnectionStrings": {
"Default": "Server=...;Database=...;"
},
"EmailSettings": {
"SmtpHost": "smtp.example.com",
"Port": 587
}
}









Strongly-typed options with validation






CODE
public class EmailSettings
{
public required string SmtpHost { get; set; }
public int Port { get; set; }
}

builder.Services
.AddOptions<EmailSettings>()
.Bind(builder.Configuration.GetSection("EmailSettings"))
.ValidateDataAnnotations()
.ValidateOnStart();









CODE
public class EmailSender(IOptions<EmailSettings> options)
{
private readonly EmailSettings _settings = options.Value;
}






ValidateOnStart() (added in .NET 8) fails fast at application startup if configuration is invalid, instead of surfacing the error deep inside a request months later.









7. Authentication and Authorization






JWT Bearer authentication






CODE
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://your-identity-provider.com";
options.Audience = "your-api";
});

builder.Services.AddAuthorization();

app.UseAuthentication();
app.UseAuthorization();









Policy-based authorization






CODE
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdmin", policy => policy.RequireRole("Admin"));
options.AddPolicy("MinimumAge", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c => c.Type == "Age" && int.Parse(c.Value) >= 18)));
});









CODE
[Authorize(Policy = "RequireAdmin")]
[HttpDelete("{id}")]
public IActionResult Delete(int id) => NoContent();









Identity and ASP.NET Core Identity



For apps needing full user management (registration, password reset, external logins), ASP.NET Core Identity provides a ready-made user store, and .NET 8 added built-in Identity API endpoints (MapIdentityApi<TUser>()) for token-based auth without hand-rolling the endpoints yourself.









8. Performance Features



ASP.NET Core's performance reputation comes from a combination of the runtime (Kestrel, the built-in web server) and framework-level design choices.






Kestrel: the built-in web server



Kestrel is a cross-platform, event-driven web server built directly on top of libuv/managed sockets. It's fast enough to be used directly in production (often behind a reverse proxy like Nginx, YARP, or a cloud load balancer for TLS termination and multiplexing).






Response caching and output caching






CODE
builder.Services.AddOutputCache(options =>
{
options.AddPolicy("Expire60", b => b.Expire(TimeSpan.FromSeconds(60)));
});

app.UseOutputCache();

app.MapGet("/weather", () => GetWeatherForecast())
.CacheOutput("Expire60");






Output caching (added in .NET 7) caches the full response server-side, avoiding recomputation for repeated identical requests — a major win for read-heavy endpoints.






Response compression






CODE
builder.Services.AddResponseCompression(options =>
{
options.EnableForHttps = true;
options.Providers.Add<BrotliCompressionProvider>();
});









Rate limiting (.NET 7+)






CODE
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("fixed", opt =>
{
opt.Window = TimeSpan.FromSeconds(10);
opt.PermitLimit = 20;
});
});

app.UseRateLimiter();

app.MapGet("/data", () => "ok").RequireRateLimiting("fixed");






Built-in rate limiting removes the need for a third-party package for common scenarios (fixed window, sliding window, token bucket, concurrency limiting).






Native AOT (.NET 8+)



Ahead-of-time compilation produces a self-contained native executable with no JIT step, drastically reducing cold-start time and memory footprint — ideal for containers and serverless functions:




CODE
dotnet publish -r linux-x64 -c Release /p:PublishAot=true






Native AOT currently works best with minimal APIs and trimmable code (some reflection-heavy libraries need adaptation).






HTTP/2, HTTP/3, and gRPC



Kestrel supports HTTP/2 and HTTP/3 (QUIC) out of the box, and ASP.NET Core has first-class support for gRPC for high-performance, strongly-typed service-to-service communication — a common backend-for-backend alternative to REST.









9. Testing and Observability






Integration testing with WebApplicationFactory






CODE
public class ProductsApiTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly HttpClient _client;

public ProductsApiTests(WebApplicationFactory<Program> factory) =>
_client = factory.CreateClient();

[Fact]
public async Task GetProduct_ReturnsOk()
{
var response = await _client.GetAsync("/products/1");
response.EnsureSuccessStatusCode();
}
}






WebApplicationFactory<TEntryPoint> spins up an in-memory test server using your real Program.cs configuration, letting you test the full middleware pipeline without a real network hop.






Health checks






CODE
builder.Services.AddHealthChecks()
.AddSqlServer(connectionString)
.AddCheck<CustomHealthCheck>("custom");

app.MapHealthChecks("/health");









OpenTelemetry (built-in support since .NET 8)






CODE
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing.AddAspNetCoreInstrumentation().AddHttpClientInstrumentation())
.WithMetrics(metrics => metrics.AddAspNetCoreInstrumentation());






Distributed tracing and metrics are now first-class, framework-level concerns rather than something bolted on via a separate agent.









Quick Reference Table




































































Feature Introduced Problem it Solves
Minimal hosting model .NET 6 Program.cs/Startup.cs split boilerplate
Minimal APIs .NET 6 Heavyweight controllers for small services
Route groups .NET 7 Repeating config across related endpoints
Typed results .NET 7 Untyped IResult return values
Keyed DI services .NET 8 Multiple implementations of one interface
ValidateOnStart() .NET 8 Late-discovered configuration errors
Output caching .NET 7 Recomputing identical responses
Rate limiting middleware .NET 7 Third-party rate-limit packages
Native AOT .NET 8 Slow cold starts, high memory footprint
Built-in OpenTelemetry .NET 8 Bolted-on tracing/metrics agents
Identity API endpoints .NET 8 Hand-rolled auth endpoints








Conclusion



ASP.NET Core's evolution has been about removing friction without removing power: minimal APIs and the unified Program.cs cut boilerplate for small services, while controllers, Razor Pages, and Blazor remain available for larger, more structured applications. Underneath it all, the framework keeps investing in things that matter at scale — Kestrel's raw throughput, built-in caching and rate limiting, native AOT for fast cold starts, and first-class observability — so that the same framework can comfortably run a five-line prototype and a production system handling millions of requests a day.



The common thread is that ASP.NET Core increasingly lets you pay only for the complexity you actually need, while making the on-ramp to production-grade performance, security, and observability a built-in part of the framework rather than a pile of third-party packages.






Found this useful? Feel free to star the repo, open an issue with corrections, or share which ASP.NET Core feature has saved you the most time.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
Use custom web fonts in Google Sheets charts
2 Quellen
Introducing the new 1Password App for Google Chat
1 Quelle
Context-aware access controls are available for Gemini Enterprise in the Admin console
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten ASP.NET Core: Building High-Performance Web Applications and APIs

Thematisch verwandte Begriffe: ASPNET, Core, Building, HighPerformance · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...