Von der ersten Projekteinrichtung mit der .NET-CLI bis zur Konfiguration von Middleware, Controllern und Diensten lernen Sie jeden Schritt zum Aufbau einer robusten API. Entdecken Sie Best Practices für die Abhängigkeitsinjektion, asynchrone Aktionen und die Behandlung von Ausnahmen, um skalierbare, effiziente Webanwendungen zu erstellen.
1. Einrichten eines .NET 8-Web-API-Projekts
Konzept
Verwenden Sie die .NET-CLI, um ein neues Web-API-Projekt zu erstellen. Dadurch wird eine grundlegende Projektstruktur eingerichtet, einschließlich Program.cs für den Start und eines WeatherForecast-Controllers als Beispiel.
Codebeispiel
dotnet new webapi -n MyWebApi
2. Program.cs – Minimale API-Konfiguration
Konzept
.NET 8 setzt den Trend zu minimalen APIs fort und ermöglicht Ihnen die einfache und übersichtliche Konfiguration von Diensten und Endpunkten direkt in der Datei Program.cs.
Codebeispiel
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Hello, World!"); app.Run();
3. Definieren eines Controllers
Konzept
Controller verarbeiten eingehende HTTP-Anfragen und antworten dem Client. Sie werden durch Erben von ControllerBase und Annotieren mit [ApiController] definiert.
Codebeispiel
[ApiController] [Route("[controller]")] public class MyController : ControllerBase { [HttpGet] public IActionResult Get() => Ok("Hello from MyController"); }
4. Abhängigkeitsinjektion in Controllern
Konzept
Die integrierte Abhängigkeitsinjektion (DI) von .NET Core erleichtert die Verwaltung von Abhängigkeiten. Sie können Dienste über deren Konstruktoren in Ihre Controller einschleusen.
Codebeispiel
public class MyService { public string GetMessage() => "Injected message"; } public class MyController : ControllerBase { private readonly MyService _myService; public MyController(MyService myService) { _myService = myService; } [HttpGet] public IActionResult Get() => Ok(_myService.GetMessage()); }
5. Dienste konfigurieren
Konzept
Dienste (wie Datenbankkontexte, benutzerdefinierte Dienste usw.) werden in der Datei „Program.cs“ konfiguriert, sodass sie für die Abhängigkeitsinjektion in Ihrer gesamten Anwendung verfügbar sind.
Codebeispiel
builder.Services.AddScoped<MyService>();
6. Umgebungsbasierte Konfiguration
Konzept
.NET unterstützt umgebungsspezifische Konfigurationsdateien (appsettings.json, appsettings.Development.json usw.) und ermöglicht so unterschiedliche Einstellungen je nach Anwendungsumgebung.
Codebeispiel
// appsettings.Development.json { "Logging": { "LogLevel": { "Default": "Debug" } } }
7. Middleware
Konzept
Middleware-Komponenten bilden eine Pipeline, die Anfragen und Antworten verarbeitet. Für übergreifende Anliegen wie Protokollierung oder Fehlerbehandlung kann benutzerdefinierte Middleware erstellt werden.
Codebeispiel
app.Use(async (context, next) => { // Custom logic before passing to the next middleware await next(); // Custom logic after executing the next middleware });
8. Routenführung
Konzept
Das Routing in der .NET-Web-API wird durch Attributrouting auf Controllern und Aktionsmethoden erreicht. Dadurch können URLs direkt Controller-Aktionen zugeordnet werden.
Codebeispiel
[HttpGet("myaction/{id}")] public IActionResult GetAction(int id) => Ok($"Action with ID = {id}");
9. Modellbindung
Konzept
Die Modellbindung ordnet Daten aus HTTP-Anfragen automatisch Aktionsmethodenparametern zu. Es unterstützt komplexe Typen, einschließlich JSON-Körper und Abfragezeichenfolgenparameter.
Codebeispiel
public class MyModel { public int Id { get; set; } public string Name { get; set; } } [HttpPost] public IActionResult PostAction([FromBody] MyModel model) => Ok(model);
10. Datenvalidierung
Konzept
Datenanmerkungen können zur Validierung von Modelldaten verwendet werden. Das [ApiController]-Attribut erzwingt automatisch die Validierung und antwortet mit 400, wenn das Modell ungültig ist.
Codebeispiel
public class MyModel { [Required] public int Id { get; set; } [StringLength(100)] public string Name { get; set; } }
11. Asynchrone Aktionen
Konzept
Asynchrone Aktionen verbessern die Skalierbarkeit, indem sie Threads freigeben, während sie auf den Abschluss von E/A-Vorgängen warten. Verwenden Sie das Schlüsselwort async und geben Sie Task oder Task<IActionResult> zurück.
Codebeispiel
[HttpGet("{id}")] public async Task<IActionResult> GetAsync(int id) { var result = await _service.GetByIdAsync(id); return Ok(result); }
12. Ausnahmen global behandeln
Konzept
Die globale Ausnahmebehandlung ermöglicht eine zentralisierte Fehlerverarbeitung, Protokollierung und standardisierte API-Antworten auf nicht behandelte Ausnahmen.
Codebeispiel
app.UseExceptionHandler(a => a.Run(async context => { var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>(); var exception = exceptionHandlerPathFeature.Error; // Log the exception, generate a custom response, etc. context.Response.StatusCode = 500; await context.Response.WriteAsJsonAsync(new { Error = "An unexpected error occurred" }); }));
13. API-Versionierung
Konzept
Die API-Versionierung hilft dabei, Änderungen an der API im Laufe der Zeit zu verwalten. Die .NET-Plattform unterstützt die Versionierung über Abfragezeichenfolge, URL-Pfad oder Anforderungsheader.
Codebeispiel
builder.Services.AddApiVersioning(options => { options.AssumeDefaultVersionWhenUnspecified = true; options.DefaultApiVersion = new ApiVersion(1, 0); options.ReportApiVersions = true; });
14. Inhaltsverhandlung
Konzept
Durch die Inhaltsverhandlung kann eine API verschiedene Antwortformate basierend auf dem Accept-Header in der Anfrage bereitstellen und so Formate wie JSON, XML usw. unterstützen.
Codebeispiel
builder.Services.AddControllers() .AddXmlDataContractSerializerFormatters();
15. Benutzerdefinierte JSON-Serialisierungseinstellungen
Konzept
Passen Sie die JSON-Antwortformatierung an, z. B. die Benennung von CamelCase oder das Ignorieren von Nullwerten, indem Sie die JSON-Serialisierungseinstellungen konfigurieren.
Codebeispiel
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.JsonSerializerOptions.IgnoreNullValues = true; });
16. CORS konfigurieren
Konzept
Cross-Origin Resource Sharing (CORS) ermöglicht den Aufruf Ihrer API von Webanwendungen, die auf verschiedenen Domänen gehostet werden. Konfigurieren Sie die CORS-Richtlinie gemäß Ihren Anforderungen.
Codebeispiel
builder.Services.AddCors(options => { options.AddPolicy("AllowSpecificOrigin", builder => builder.WithOrigins("http://example.com")); }); app.UseCors("AllowSpecificOrigin");
17. Authentifizierung
Konzept
Sichern Sie Ihre API, indem Sie die Authentifizierung aktivieren, die die Identität von Benutzern oder Diensten überprüft, die Anfragen stellen.
Codebeispiel
builder.Services.AddAuthentication("Bearer") .AddJwtBearer(options => { options.Authority = "https://your-auth-server"; options.Audience = "your-api"; });
18. Autorisierung
Konzept
Nach der Authentifizierung bestimmt die Autorisierung, ob ein authentifizierter Benutzer berechtigt ist, eine Aktion auszuführen oder auf eine Ressource zuzugreifen.
Codebeispiel
[Authorize] public class SecureController : ControllerBase { // Action methods here }
19. Swagger/OpenAPI-Integration
Konzept
Swagger (OpenAPI) bietet interaktive Dokumentation für Ihre API, sodass Entwickler sie leicht verstehen und nutzen können.
Codebeispiel
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); app.UseSwagger(); app.UseSwaggerUI();
20. Protokollierung
Konzept
.NET Core bietet ein integriertes Protokollierungsframework, das Nachrichten an verschiedenen Ausgaben (Konsole, Debug-Fenster, externe Dienste usw.) protokollieren kann.
Codebeispiel
logger.LogInformation("This is an informational message"); app.Use(async (context, next) => { logger.LogError("This is an error message before the next middleware"); await next.Invoke(); // Log after calling the next middleware });
21. Verwendung von Entity Framework Core
Konzept
Entity Framework Core ist ein ORM, das für den Datenzugriff in .NET-Anwendungen verwendet wird. Es ermöglicht Ihnen, Daten mithilfe stark typisierter Objekte abzufragen und zu bearbeiten.
Codebeispiel
public class MyDbContext : DbContext { public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) {} public DbSet<MyModel> MyModels { get; set; } }
22. Migrationen im Entity Framework Core
Konzept
Mit Migrationen können Sie die Versionskontrolle auf Ihr Datenbankschema anwenden, indem Sie Änderungen in Ihren Datenmodellen verfolgen.
Codebeispiel
dotnet ef migrations add InitialCreate dotnet ef database update
23. Repository-Muster
Konzept
Das Repository-Muster abstrahiert die Datenschicht und macht Ihre Anwendung modularer und einfacher zu warten.
Codebeispiel
public interface IRepository<T> { Task<IEnumerable<T>> GetAllAsync(); Task<T> GetByIdAsync(int id); // Other methods... } public class MyRepository<T> : IRepository<T> where T : class { private readonly MyDbContext _context; public MyRepository(MyDbContext context) { _context = context; } // Implement methods... }
24. Unit-Tests
Konzept
Unit-Tests stellen sicher, dass Ihre Web-API ordnungsgemäß funktioniert, indem einzelne Codeeinheiten isoliert getestet werden.
Codebeispiel
public class MyControllerTests { [Fact] public async Task Get_ReturnsExpectedValue() { // Arrange var serviceMock = new Mock<IMyService>(); serviceMock.Setup(service => service.GetAsync()).ReturnsAsync("test"); var controller = new MyController(serviceMock.Object); // Act var result = await controller.Get(); // Assert Assert.Equal("test", result.Value); } }
25. Integration mit einem Frontend
Konzept
Die .NET-Web-API kann als Backend für eine Front-End-Anwendung dienen und RESTful-Dienste bereitstellen.
Codebeispiel
fetch('https://localhost:5001/mycontroller') .then(response => response.json()) .then(data => console.log(data));
26. Gesundheitschecks
Konzept
Gesundheitsprüfungen bieten eine Möglichkeit, den Status Ihrer Anwendung und ihrer Abhängigkeiten zu überwachen, was für Microservices-Architekturen nützlich ist.
Codebeispiel
builder.Services.AddHealthChecks(); app.MapHealthChecks("/health");
27. Verwendung von SignalR für Echtzeitkommunikation
Konzept
SignalR ermöglicht Echtzeit-Webfunktionen, sodass serverseitiger Code asynchrone Benachrichtigungen an clientseitige Webanwendungen senden kann.
Codebeispiel
public class MyHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); } }
28. Antwort-Caching konfigurieren
Konzept
Das Zwischenspeichern von Antworten reduziert die Anzahl der Anfragen, die ein Server bearbeiten muss, indem eine Kopie der zuvor angeforderten Ressourcen gespeichert wird.
Codebeispiel
[HttpGet("{id}")] [ResponseCache(Duration = 60)] public IActionResult GetById(int id) { // Retrieve and return your resource }
29. Statische Dateien
Konzept
Die Bereitstellung statischer Dateien (HTML, CSS, JavaScript usw.) ist für die Unterstützung von Front-End-Anwendungen mit einer .NET-Web-API unerlässlich.
Codebeispiel
app.UseStaticFiles(); // Enable static file serving
30. Erweiterte Konfiguration und Optionsmuster
Konzept
Das Optionsmuster verwendet Klassen, um Gruppen verwandter Einstellungen darzustellen. Mit IOptions<T> können Sie überall in Ihrer Anwendung auf diese Einstellungen zugreifen.
Codebeispiel
public class MySettings { public string Setting1 { get; set; } // Other settings } builder.Services.Configure<MySettings>(builder.Configuration.GetSection("MySettings")); public class MyService { private readonly MySettings _settings; public MyService(IOptions<MySettings> settings) { _settings = settings.Value; } // Use _settings.Setting1 }
31. Benutzerdefinierte Middleware
Konzept
Middleware ist Software, die in eine Anwendungspipeline integriert wird, um Anfragen und Antworten zu verarbeiten. Zur Ausführung bestimmter Aufgaben kann benutzerdefinierte Middleware erstellt werden.
Codebeispiel
public class MyCustomMiddleware { private readonly RequestDelegate _next; public MyCustomMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext httpContext) { // Pre-processing logic here await _next(httpContext); // Call the next middleware in the pipeline // Post-processing logic here } } // Extension method for easy middleware registration public static class MyCustomMiddlewareExtensions { public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<MyCustomMiddleware>(); } }
32. Ratenbegrenzung
Konzept
Die Ratenbegrenzung schützt Ihre API vor Überbeanspruchung, indem sie begrenzt, wie oft ein Benutzer innerhalb eines bestimmten Zeitraums Anfragen stellen kann.
Codebeispiel
// Assume using a third-party library like AspNetCoreRateLimit builder.Services.AddInMemoryRateLimiting(); builder.Services.Configure<IpRateLimitOptions>(options => { options.GeneralRules = new List<RateLimitRule> { new RateLimitRule { Endpoint = "*", Limit = 100, Period = "1h" } }; });
33. API-Schlüsselauthentifizierung
Konzept
API-Schlüssel sind eine einfache Möglichkeit, API-Aufrufe zu authentifizieren und zu autorisieren. Sie werden entweder in der Abfragezeichenfolge oder im Header vom Client an den Server übergeben.
Codebeispiel
public class ApiKeyMiddleware { private readonly RequestDelegate _next; private const string APIKEYNAME = "x-api-key"; public ApiKeyMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { if (!context.Request.Headers.TryGetValue(APIKEYNAME, out var extractedApiKey)) { context.Response.StatusCode = 401; await context.Response.WriteAsync("API Key was not provided."); return; } // Validate the extracted API Key here... await _next(context); } }
34. Ausgabe-Caching
Konzept
Mit dem Ausgabe-Caching können Sie die Antwort auf eine Anfrage speichern. Nachfolgende Anfragen können aus dem Cache bedient werden, was die Leistung erheblich verbessert.
Codebeispiel
[HttpGet] [ResponseCache(Duration = 120, Location = ResponseCacheLocation.Client, NoStore = false)] public IActionResult Get() { // Your logic here }
35. Hintergrundaufgaben
Konzept
Hintergrundaufgaben ermöglichen die Ausführung von Vorgängen im Hintergrund, unabhängig von Benutzeranfragen, wie z. B. dem Senden von E-Mails oder der Verarbeitung lang laufender Aufträge.
Codebeispiel
public class MyBackgroundService : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { // Your background task logic here await Task.Delay(TimeSpan.FromHours(1), stoppingToken); } } }
36. WebSockets
Konzept
WebSockets bieten einen Vollduplex-Kommunikationskanal über eine einzige, langlebige Verbindung, ideal für Echtzeitanwendungen.
Codebeispiel
app.UseWebSockets(); app.Use(async (context, next) => { if (context.WebSockets.IsWebSocketRequest) { WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); // Handle the WebSocket request here } else { await next(); } });
37. Lokalisierung anfordern
Konzept
Die Anforderungslokalisierung bietet eine Möglichkeit, Inhalte für verschiedene Kulturen und Sprachen basierend auf den Informationen der Anforderung zu lokalisieren.
Codebeispiel
var supportedCultures = new[] { "en-US", "fr-FR" }; var localizationOptions = new RequestLocalizationOptions() .SetDefaultCulture(supportedCultures[0]) .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); app.UseRequestLocalization(localizationOptions);
38. Integration mit GraphQL
Konzept
GraphQL ist eine Abfragesprache für APIs. Die Integration einer .NET-Web-API mit GraphQL ermöglicht einen effizienteren Datenabruf.
Codebeispiel
// Assume using a library like HotChocolate builder.Services .AddGraphQLServer() .AddQueryType<Query>(); app.MapGraphQL();
39. Überwachung und Telemetrie
Konzept
Überwachung und Telemetrie umfassen das Sammeln, Analysieren und Reagieren auf Daten über die Leistung und Nutzung Ihrer Anwendung.
Codebeispiel
// Assume using Application Insights builder.Services.AddApplicationInsightsTelemetry("YOUR_INSTRUMENTATION_KEY");
40. SignalR-Hubs und Echtzeitkommunikation
Konzept
SignalR ist eine Bibliothek, die das Hinzufügen von Echtzeit-Webfunktionen zu Apps vereinfacht. Echtzeit-Webfunktionalität ist die Möglichkeit, dass Servercode Inhalte sofort an verbundene Clients weiterleitet, ohne dass der Server darauf warten muss, dass ein Client neue Daten anfordert. SignalR eignet sich perfekt für die Entwicklung von Chat-Anwendungen, Echtzeit-Dashboards und interaktiveren Webanwendungen.
Codebeispiel
public class ChatHub : Hub { public async Task SendMessage(string user, string message) { // Call the broadcastMessage method to update clients. await Clients.All.SendAsync("broadcastMessage", user, message); } } // Startup or Program.cs app.MapHub<ChatHub>("/chathub");
Integration in Program.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // Other configurations... app.UseEndpoints(endpoints => { endpoints.MapHub<ChatHub>("/chathub"); }); }
41. Advanced Entity Framework Core – Beziehungen
Konzept
Entity Framework Core ermöglicht die Abbildung komplexer Beziehungen zwischen Entitäten, z. B. Eins-zu-Eins, Eins-zu-Viele und Viele-zu-Viele.
Codebeispiel
public class Author { public int AuthorId { get; set; } public string Name { get; set; } public ICollection<Book> Books { get; set; } } public class Book { public int BookId { get; set; } public string Title { get; set; } public int AuthorId { get; set; } public Author Author { get; set; } }
42. Benutzerdefinierte Validierungsattribute
Konzept
Mit benutzerdefinierten Validierungsattributen können Sie Ihre Validierungslogik für Datenmodelle definieren und die integrierten Validierungsattribute erweitern.
Codebeispiel
public class MyCustomValidationAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { // Your custom validation logic here if (value is int intValue && intValue > 0) { return ValidationResult.Success; } return new ValidationResult("Value must be positive"); } } public class MyModel { [MyCustomValidationAttribute] public int MyProperty { get; set; } }
43. Erweiterte Konfigurationsszenarien
Konzept
Das Optionsmuster von .NET unterstützt komplexe Konfigurationsszenarien, einschließlich verschachtelter Objekte, Listen und Validierung.
Codebeispiel
public class MyOptions { public MyNestedOptions Nested { get; set; } public List<string> Items { get; set; } } public class MyNestedOptions { public string Key { get; set; } } // In Program.cs or Startup.cs builder.Services.Configure<MyOptions>(builder.Configuration.GetSection("MyOptions"));
44. Leistungsüberwachung und Profilerstellung
Konzept
Durch die Überwachung und Profilierung einer Anwendung können Engpässe und Ineffizienzen identifiziert werden, was für die Optimierung der Leistung unerlässlich ist.
Codebeispiel
app.UseMiniProfiler();
45. API-Dokumentation mit Swagger und XML-Kommentaren
Konzept
Erweitern Sie Ihre API-Dokumentation, indem Sie XML-Kommentare in Ihre Swagger-Benutzeroberfläche integrieren und so Entwicklern, die Ihre API nutzen, ein umfassenderes Erlebnis bieten.
Codebeispiel
builder.Services.AddSwaggerGen(c => { var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); });
46. Globalisierung und Lokalisierung
Konzept
Globalisierung und Lokalisierung ermöglichen es Ihrer Anwendung, mehrere Sprachen und Kulturen zu unterstützen und sie so einem globalen Publikum zugänglich zu machen.
Codebeispiel
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); app.UseRequestLocalization(app.Services.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value);
47. Sicherheitsheader
Konzept
Die Verbesserung der Sicherheit Ihrer Webanwendung durch das Hinzufügen verschiedener HTTP-Header kann Sie vor häufigen Angriffen und Schwachstellen schützen.
Codebeispiel
app.UseHsts(); app.UseXContentTypeOptions(); app.UseReferrerPolicy(opts => opts.NoReferrer()); app.UseXXssProtection(options => options.EnabledWithBlockMode()); app.UseXfo(options => options.Deny());
48. Feature-Flags
Konzept
Mit Feature-Flags können Sie Funktionen Ihrer Anwendung ein- und ausschalten, ohne neuen Code bereitzustellen, was einfachere Tests und Rollouts ermöglicht.
Codebeispiel
// Using a library like Microsoft.FeatureManagement builder.Services.AddFeatureManagement();
49. Blazor-Integration
Konzept
Mit Blazor können Sie interaktive Web-Benutzeroberflächen mit C# anstelle von JavaScript erstellen. Die Integration von Blazor mit der Web-API bietet ein nahtloses Full-Stack-Entwicklungserlebnis.
Codebeispiel
// In a Blazor Server app @code { private IEnumerable<WeatherForecast> forecasts; protected override async Task OnInitializedAsync() { forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast"); } }
50. Erweiterte Middleware zur Antwortkomprimierung
Konzept
Die Antwortkomprimierung kann die Größe Ihrer API-Antworten reduzieren und so die Ladezeiten für Clients über langsame Netzwerke verbessern.
Codebeispiel
builder.Services.AddResponseCompression(options => { options.Providers.Add<GzipCompressionProvider>(); options.EnableForHttps = true; }); app.UseResponseCompression();
C#-Programmierung🚀
Vielen Dank, dass Sie Teil der C#-Community sind! Bevor Sie gehen:
Wenn Sie es bis hierher geschafft haben, zeigen Sie bitte Ihre Wertschätzung mit einem Klatschen und folgen Sie dem Autor! 👏️️
Folgen Sie uns: X | LinkedIn | Dev.to | Hashnode | Newsletter | Tumblr
Besuchen Sie unsere anderen Plattformen: GitHub | Instagram | Tiktok | Quora | Daily.dev
Auch hier veröffentlicht