.NET 10: Eine REST-API mit ASP.NET Core erstellen
Vollstaendiger Leitfaden zur Erstellung einer professionellen REST-API mit .NET 10 und ASP.NET Core. Controller, Entity Framework Core, integrierte Validierung und Best Practices erklaert.

.NET 10 ist das aktuelle Long-Term-Support-Release (LTS) und bringt native Validierung fuer Minimal APIs, standardmaessige OpenAPI 3.1-Unterstuetzung sowie erhebliche Performance-Verbesserungen. ASP.NET Core kombiniert C# mit einer modularen Architektur, die fuer Unternehmensanwendungen geeignet ist. Dieser Leitfaden behandelt die Erstellung einer produktionsreifen REST-API vom initialen Setup bis zum Deployment.
.NET 10 wird bis Ende 2028 unterstuetzt. Integrierte Validierung fuer Minimal APIs, OpenAPI 3.1-Unterstuetzung und Native-AOT-Verbesserungen machen es zur optimalen Wahl fuer neue API-Projekte.
Projekt-Setup mit .NET 10 CLI
Die Erstellung eines ASP.NET Core API-Projekts erfolgt ueber die .NET CLI, die eine optimierte Projektstruktur generiert. Die Konfiguration essentieller NuGet-Pakete legt das Fundament fuer die Entwicklung.
# terminal
# Check installed .NET version
dotnet --version
# Expected: 10.0.x
# Create the API project
dotnet new webapi -n ProductApi -o ProductApi
cd ProductApi
# Add essential packages
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Swashbuckle.AspNetCoreDiese Befehle erstellen ein API-Projekt mit Abhaengigkeiten fuer Entity Framework Core und Swagger-Dokumentation. FluentValidation ist fuer grundlegende Validierung in .NET 10 nicht mehr erforderlich.
using Microsoft.EntityFrameworkCore;
using ProductApi.Data;
using ProductApi.Services;
var builder = WebApplication.CreateBuilder(args);
// Configure Entity Framework Core with SQL Server
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// Register business services
builder.Services.AddScoped<IProductService, ProductService>();
builder.Services.AddScoped<ICategoryService, CategoryService>();
// Configure controllers with built-in validation (.NET 10)
builder.Services.AddControllers();
builder.Services.AddValidation();
// Configure OpenAPI 3.1 (default in .NET 10)
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new() { Title = "Product API", Version = "v1" });
});
var app = builder.Build();
// Middleware pipeline
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();Die AddValidation()-Methode aktiviert die integrierte Validierung, die in ASP.NET Core 10 eingefuehrt wurde und Drittanbieter-Bibliotheken wie FluentValidation fuer gaengige Szenarien ueberfluessig macht.
Datenmodelle und Entity Framework Core 10
Modelle repraesentieren die Geschaeftsentitaeten der Anwendung. Entity Framework Core uebernimmt das objekt-relationale Mapping mit Fluent-Konfiguration und intelligenten Konventionen.
namespace ProductApi.Models;
public class Product
{
// Primary key with auto-increment
public int Id { get; set; }
// Required properties (non-nullable in C# 14)
public required string Name { get; set; }
public required string Description { get; set; }
// Price with decimal precision
public decimal Price { get; set; }
// Stock with default value
public int StockQuantity { get; set; } = 0;
// Product status
public bool IsActive { get; set; } = true;
// Relationship with Category (foreign key)
public int CategoryId { get; set; }
public Category? Category { get; set; }
// Automatic tracking dates
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
}Das required-Schluesselwort stellt sicher, dass essentielle Properties bei der Erstellung immer initialisiert werden.
namespace ProductApi.Models;
public class Category
{
public int Id { get; set; }
public required string Name { get; set; }
// Slug for friendly URLs
public required string Slug { get; set; }
public string? Description { get; set; }
// Inverse navigation: list of products in this category
public ICollection<Product> Products { get; set; } = new List<Product>();
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}using Microsoft.EntityFrameworkCore;
using ProductApi.Models;
namespace ProductApi.Data;
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
// DbSets for each entity
public DbSet<Product> Products => Set<Product>();
public DbSet<Category> Categories => Set<Category>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Product entity configuration
modelBuilder.Entity<Product>(entity =>
{
// Index on name for fast search
entity.HasIndex(p => p.Name);
// Price precision: 18 digits, 2 decimals
entity.Property(p => p.Price)
.HasPrecision(18, 2);
// Relationship with Category
entity.HasOne(p => p.Category)
.WithMany(c => c.Products)
.HasForeignKey(p => p.CategoryId)
.OnDelete(DeleteBehavior.Restrict);
});
// Category entity configuration
modelBuilder.Entity<Category>(entity =>
{
// Unique slug
entity.HasIndex(c => c.Slug).IsUnique();
// Maximum name length
entity.Property(c => c.Name).HasMaxLength(100);
});
}
}Die Fluent-API-Konfiguration bietet praezise Kontrolle ueber das von EF Core Migrations generierte Datenbankschema.
Migrations versionieren das Datenbankschema. dotnet ef migrations add InitialCreate gefolgt von dotnet ef database update wendet die Aenderungen an.
DTOs und integrierte Validierung in ASP.NET Core 10
DTOs (Data Transfer Objects) trennen Domaenenmodelle von den ueber die API bereitgestellten Daten. ASP.NET Core 10 fuehrt integrierte Validierung mit DataAnnotations ein und macht Drittanbieter-Bibliotheken in den meisten Faellen ueberfluessig.
using System.ComponentModel.DataAnnotations;
namespace ProductApi.DTOs;
// DTO for product creation with DataAnnotations
public record CreateProductDto(
[Required(ErrorMessage = "Product name is required.")]
[MaxLength(200, ErrorMessage = "Name cannot exceed 200 characters.")]
string Name,
[Required(ErrorMessage = "Description is required.")]
[MinLength(10, ErrorMessage = "Description must contain at least 10 characters.")]
string Description,
[Range(0.01, 999999.99, ErrorMessage = "Price must be between 0.01 and 999,999.99.")]
decimal Price,
[Range(0, int.MaxValue, ErrorMessage = "Stock cannot be negative.")]
int StockQuantity,
[Required(ErrorMessage = "A valid category is required.")]
int CategoryId
);
// DTO for product update
public record UpdateProductDto(
[MaxLength(200)]
string? Name,
string? Description,
[Range(0.01, 999999.99)]
decimal? Price,
[Range(0, int.MaxValue)]
int? StockQuantity,
bool? IsActive
);
// DTO for response (read)
public record ProductDto(
int Id,
string Name,
string Description,
decimal Price,
int StockQuantity,
bool IsActive,
string CategoryName,
DateTime CreatedAt
);
// DTO for list with pagination
public record ProductListDto(
int Id,
string Name,
decimal Price,
int StockQuantity,
bool IsActive,
string CategoryName
);Die Verwendung von C# Records macht DTOs unveraenderlich und praegnant, mit automatischer Wertgleichheit. Die integrierte Validierung gibt automatisch strukturierte 400-Fehler zurueck, wenn die Validierung fehlschlaegt. Zur Vorbereitung auf Vorstellungsgespraeche zu ASP.NET Core-Patterns siehe den Leitfaden ASP.NET Core Interviewfragen.
Bereit für deine .NET-Interviews?
Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.
Business-Services und Abstraktionsschicht
Die Service-Schicht kapselt Geschaeftslogik und Datenbankoperationen und erleichtert so das Testen und die Wartung.
using ProductApi.DTOs;
namespace ProductApi.Services;
public interface IProductService
{
// Retrieval with pagination
Task<(IEnumerable<ProductListDto> Items, int TotalCount)> GetAllAsync(
int page = 1,
int pageSize = 10,
string? search = null,
int? categoryId = null);
// Retrieval by ID
Task<ProductDto?> GetByIdAsync(int id);
// Creation
Task<ProductDto> CreateAsync(CreateProductDto dto);
// Update
Task<ProductDto?> UpdateAsync(int id, UpdateProductDto dto);
// Deletion
Task<bool> DeleteAsync(int id);
}using Microsoft.EntityFrameworkCore;
using ProductApi.Data;
using ProductApi.DTOs;
using ProductApi.Models;
namespace ProductApi.Services;
public class ProductService : IProductService
{
private readonly AppDbContext _context;
public ProductService(AppDbContext context)
{
_context = context;
}
public async Task<(IEnumerable<ProductListDto> Items, int TotalCount)> GetAllAsync(
int page = 1,
int pageSize = 10,
string? search = null,
int? categoryId = null)
{
// Build base query
var query = _context.Products
.Include(p => p.Category)
.AsQueryable();
// Filter by text search
if (!string.IsNullOrWhiteSpace(search))
{
query = query.Where(p =>
p.Name.Contains(search) ||
p.Description.Contains(search));
}
// Filter by category
if (categoryId.HasValue)
{
query = query.Where(p => p.CategoryId == categoryId.Value);
}
// Total count before pagination
var totalCount = await query.CountAsync();
// Apply pagination
var items = await query
.OrderByDescending(p => p.CreatedAt)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.Select(p => new ProductListDto(
p.Id,
p.Name,
p.Price,
p.StockQuantity,
p.IsActive,
p.Category!.Name))
.ToListAsync();
return (items, totalCount);
}
public async Task<ProductDto?> GetByIdAsync(int id)
{
// Retrieve with category inclusion
var product = await _context.Products
.Include(p => p.Category)
.FirstOrDefaultAsync(p => p.Id == id);
if (product == null) return null;
// Map to DTO
return new ProductDto(
product.Id,
product.Name,
product.Description,
product.Price,
product.StockQuantity,
product.IsActive,
product.Category?.Name ?? "Uncategorized",
product.CreatedAt);
}
public async Task<ProductDto> CreateAsync(CreateProductDto dto)
{
// Create entity
var product = new Product
{
Name = dto.Name,
Description = dto.Description,
Price = dto.Price,
StockQuantity = dto.StockQuantity,
CategoryId = dto.CategoryId
};
// Add and save
_context.Products.Add(product);
await _context.SaveChangesAsync();
// Load category for response
await _context.Entry(product)
.Reference(p => p.Category)
.LoadAsync();
return new ProductDto(
product.Id,
product.Name,
product.Description,
product.Price,
product.StockQuantity,
product.IsActive,
product.Category?.Name ?? "Uncategorized",
product.CreatedAt);
}
public async Task<ProductDto?> UpdateAsync(int id, UpdateProductDto dto)
{
// Retrieve existing entity
var product = await _context.Products
.Include(p => p.Category)
.FirstOrDefaultAsync(p => p.Id == id);
if (product == null) return null;
// Conditional field updates
if (!string.IsNullOrEmpty(dto.Name))
product.Name = dto.Name;
if (!string.IsNullOrEmpty(dto.Description))
product.Description = dto.Description;
if (dto.Price.HasValue)
product.Price = dto.Price.Value;
if (dto.StockQuantity.HasValue)
product.StockQuantity = dto.StockQuantity.Value;
if (dto.IsActive.HasValue)
product.IsActive = dto.IsActive.Value;
// Update modification date
product.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
return new ProductDto(
product.Id,
product.Name,
product.Description,
product.Price,
product.StockQuantity,
product.IsActive,
product.Category?.Name ?? "Uncategorized",
product.CreatedAt);
}
public async Task<bool> DeleteAsync(int id)
{
// Direct deletion without prior loading (EF Core 7+)
var result = await _context.Products
.Where(p => p.Id == id)
.ExecuteDeleteAsync();
return result > 0;
}
}Die Verwendung von ExecuteDeleteAsync verbessert die Performance, da das Laden der Entitaet vor dem Loeschen entfaellt. Fuer fortgeschrittene Patterns siehe den Leitfaden Clean Architecture mit .NET.
API-Controller und REST-Endpunkte
Controller stellen REST-Endpunkte bereit und orchestrieren Aufrufe an Business-Services mit angemessener HTTP-Statuscode-Behandlung.
using Microsoft.AspNetCore.Mvc;
using ProductApi.DTOs;
using ProductApi.Services;
namespace ProductApi.Controllers;
[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class ProductsController : ControllerBase
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
/// <summary>
/// Retrieves the list of products with pagination and filters.
/// </summary>
[HttpGet]
[ProducesResponseType(typeof(PaginatedResponse<ProductListDto>), StatusCodes.Status200OK)]
public async Task<IActionResult> GetAll(
[FromQuery] int page = 1,
[FromQuery] int pageSize = 10,
[FromQuery] string? search = null,
[FromQuery] int? categoryId = null)
{
// Validate pagination parameters
if (page < 1) page = 1;
if (pageSize < 1 || pageSize > 100) pageSize = 10;
var (items, totalCount) = await _productService.GetAllAsync(
page, pageSize, search, categoryId);
// Standardized paginated response
var response = new PaginatedResponse<ProductListDto>
{
Items = items,
Page = page,
PageSize = pageSize,
TotalCount = totalCount,
TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize)
};
return Ok(response);
}
/// <summary>
/// Retrieves a product by its identifier.
/// </summary>
[HttpGet("{id:int}")]
[ProducesResponseType(typeof(ProductDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetById(int id)
{
var product = await _productService.GetByIdAsync(id);
if (product == null)
{
return NotFound(new { message = $"Product with ID {id} not found." });
}
return Ok(product);
}
/// <summary>
/// Creates a new product.
/// </summary>
[HttpPost]
[ProducesResponseType(typeof(ProductDto), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create([FromBody] CreateProductDto dto)
{
// Validation is automatic via AddValidation()
var product = await _productService.CreateAsync(dto);
// Returns 201 with the created resource URL
return CreatedAtAction(
nameof(GetById),
new { id = product.Id },
product);
}
/// <summary>
/// Updates an existing product.
/// </summary>
[HttpPut("{id:int}")]
[ProducesResponseType(typeof(ProductDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Update(int id, [FromBody] UpdateProductDto dto)
{
var product = await _productService.UpdateAsync(id, dto);
if (product == null)
{
return NotFound(new { message = $"Product with ID {id} not found." });
}
return Ok(product);
}
/// <summary>
/// Deletes a product.
/// </summary>
[HttpDelete("{id:int}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> Delete(int id)
{
var deleted = await _productService.DeleteAsync(id);
if (!deleted)
{
return NotFound(new { message = $"Product with ID {id} not found." });
}
// 204 No Content for successful deletion
return NoContent();
}
}Die ProducesResponseType-Attribute dokumentieren moegliche Antwortcodes fuer die automatische Swagger-Dokumentationsgenerierung.
namespace ProductApi.DTOs;
public class PaginatedResponse<T>
{
public IEnumerable<T> Items { get; set; } = Enumerable.Empty<T>();
public int Page { get; set; }
public int PageSize { get; set; }
public int TotalCount { get; set; }
public int TotalPages { get; set; }
public bool HasPreviousPage => Page > 1;
public bool HasNextPage => Page < TotalPages;
}Die Verwendung von Constraints wie {id:int} verhindert Routing-Konflikte und gibt automatisch einen 404-Fehler zurueck, wenn das Format nicht stimmt.
Globale Fehlerbehandlungs-Middleware
Eine Fehlerbehandlungs-Middleware zentralisiert die Ausnahmeverarbeitung fuer konsistente und sichere Antworten.
using System.Net;
using System.Text.Json;
namespace ProductApi.Middleware;
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionMiddleware> _logger;
private readonly IHostEnvironment _env;
public ExceptionMiddleware(
RequestDelegate next,
ILogger<ExceptionMiddleware> logger,
IHostEnvironment env)
{
_next = next;
_logger = logger;
_env = env;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
// Continue pipeline
await _next(context);
}
catch (Exception ex)
{
// Log the error
_logger.LogError(ex, "An unhandled exception occurred");
// Prepare response
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
// Different response based on environment
var response = _env.IsDevelopment()
? new ErrorResponse(
StatusCode: context.Response.StatusCode,
Message: ex.Message,
Details: ex.StackTrace)
: new ErrorResponse(
StatusCode: context.Response.StatusCode,
Message: "An internal error occurred.",
Details: null);
// Serialize with camelCase options
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var json = JsonSerializer.Serialize(response, options);
await context.Response.WriteAsync(json);
}
}
}
// DTO for error responses
public record ErrorResponse(int StatusCode, string Message, string? Details);
// Extension to register middleware
public static class ExceptionMiddlewareExtensions
{
public static IApplicationBuilder UseExceptionMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<ExceptionMiddleware>();
}
}var app = builder.Build();
// Exception middleware must be first
app.UseExceptionMiddleware();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
// ... rest of configurationKonfiguration und Umgebungsvariablen
Externalisierte Konfiguration ermoeglicht die Anpassung der Anwendung an verschiedene Umgebungen ohne Codeaenderungen.
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=ProductDb;User Id=sa;Password=YourPassword;TrustServerCertificate=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore": "Warning"
}
},
"ApiSettings": {
"DefaultPageSize": 10,
"MaxPageSize": 100,
"ApiVersion": "1.0"
}
}namespace ProductApi.Configuration;
public class ApiSettings
{
public int DefaultPageSize { get; set; } = 10;
public int MaxPageSize { get; set; } = 100;
public string ApiVersion { get; set; } = "1.0";
}builder.Services.Configure<ApiSettings>(
builder.Configuration.GetSection("ApiSettings"));
// Usage in a service
public class ProductService : IProductService
{
private readonly ApiSettings _settings;
public ProductService(IOptions<ApiSettings> settings)
{
_settings = settings.Value;
}
}Unit-Tests mit xUnit
Unit-Tests validieren das Verhalten von Services und Controllern isoliert.
using Microsoft.EntityFrameworkCore;
using ProductApi.Data;
using ProductApi.DTOs;
using ProductApi.Models;
using ProductApi.Services;
using Xunit;
namespace ProductApi.Tests;
public class ProductServiceTests
{
private AppDbContext CreateInMemoryContext()
{
// Configure in-memory database
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
.Options;
return new AppDbContext(options);
}
[Fact]
public async Task CreateAsync_ValidDto_ReturnsProductDto()
{
// Arrange
using var context = CreateInMemoryContext();
// Add test category
var category = new Category { Id = 1, Name = "Electronics", Slug = "electronics" };
context.Categories.Add(category);
await context.SaveChangesAsync();
var service = new ProductService(context);
var dto = new CreateProductDto(
Name: "Test Product",
Description: "Test Description",
Price: 99.99m,
StockQuantity: 10,
CategoryId: 1);
// Act
var result = await service.CreateAsync(dto);
// Assert
Assert.NotNull(result);
Assert.Equal("Test Product", result.Name);
Assert.Equal(99.99m, result.Price);
Assert.Equal("Electronics", result.CategoryName);
}
[Fact]
public async Task GetByIdAsync_NonExistent_ReturnsNull()
{
// Arrange
using var context = CreateInMemoryContext();
var service = new ProductService(context);
// Act
var result = await service.GetByIdAsync(999);
// Assert
Assert.Null(result);
}
[Fact]
public async Task DeleteAsync_ExistingProduct_ReturnsTrue()
{
// Arrange
using var context = CreateInMemoryContext();
var category = new Category { Id = 1, Name = "Test", Slug = "test" };
var product = new Product
{
Id = 1,
Name = "To Delete",
Description = "Will be deleted",
Price = 10.00m,
CategoryId = 1
};
context.Categories.Add(category);
context.Products.Add(product);
await context.SaveChangesAsync();
var service = new ProductService(context);
// Act
var result = await service.DeleteAsync(1);
// Assert
Assert.True(result);
Assert.Null(await context.Products.FindAsync(1));
}
}Tests werden mit dotnet test vom Projektstammverzeichnis aus ausgefuehrt. Fuer mehr zu EF Core Performance-Patterns, einschliesslich Teststrategien, siehe den dedizierten Leitfaden.
Sources
- What's new in ASP.NET Core 10 - Integrierte Validierung, OpenAPI 3.1-Unterstuetzung
- What's new in .NET 10 - LTS-Release-Details, C# 14-Features
- Entity Framework Core documentation - EF Core 10-Updates
- Announcing .NET 10 - Offizielle Release-Ankuendigung
Checkliste fuer produktionsreife .NET-APIs
.NET 10 mit ASP.NET Core bietet ein vollstaendiges und performantes Oekosystem fuer die Erstellung professioneller REST-APIs. Die Kombination aus integrierter Validierung, Entity Framework Core fuer den Datenzugriff und nativer Dependency Injection ermoeglicht wartbare und testbare Anwendungen.
- Separate DTOs von Domaenenmodellen
- Service-Schicht fuer Geschaeftslogik implementieren
- Integrierte Validierung mit DataAnnotations nutzen (.NET 10+)
- Globale Fehlerbehandlungs-Middleware konfigurieren
- Konfiguration mit IOptions externalisieren
- Unit-Tests fuer Services schreiben
- API mit OpenAPI 3.1 dokumentieren
Fang an zu üben!
Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.
Die geschichtete Architektur (Controller, Services, Repository/DbContext) foerdert die Trennung von Verantwortlichkeiten und erleichtert die Weiterentwicklung der Anwendung. .NET 10-Features wie integrierte Validierung, standardmaessige OpenAPI 3.1-Unterstuetzung und verbesserte Native-AOT-Unterstuetzung modernisieren die API-Entwicklung und verbessern gleichzeitig die Performance.
Findest du den Bug in .NET?
Ein echter Codeausschnitt, ein versteckter Bug, ein Versuch pro Tag. Zum Ausprobieren ohne Konto.

Geschrieben von
Anthony Fillion-MailletGründer von SharpSkill
Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.
Aktualisiert am 22. August 2026
Tags
Teilen
Verwandte Artikel

Clean Architecture mit .NET: Praktischer Leitfaden
Clean Architecture in .NET mit C# beherrschen. SOLID-Prinzipien, Schichtentrennung und Implementierungsmuster für wartbare Anwendungen kennenlernen.

C# und .NET Interview-Fragen: Vollstaendiger Leitfaden 2026
Die 17 haeufigsten C#- und .NET-Interviewfragen. LINQ, async/await, Dependency Injection, Entity Framework Core und Best Practices mit ausfuehrlichen Antworten.

.NET 10 im Jahr 2026: Neue Features, Native AOT und C# 14 fuer die Interview-Vorbereitung
.NET 10 erscheint als Long-Term-Support-Version mit Native-AOT-Verbesserungen, C# 14 Extension Members, dem field-Keyword und dateibasierten Apps. Ein vollstaendiger Leitfaden zu neuen Features, Leistungsgewinnen und interview-relevantem Wissen fuer .NET-Entwickler 2026.