A comprehensive ASP.NET Core response wrapper that transforms your APIs into enterprise-grade endpoints with zero code changes. Automatically wraps controller responses in a consistent format with rich metadata including execution timing, correlation IDs, request tracking, and comprehensive error handling. Features intelligent application status code extraction and promotion for complex workflow management, automatic pagination metadata separation using duck typing (works with ANY pagination library), database query statistics integration, and extensive configuration options. Includes built-in exception types for common scenarios (ValidationException, NotFoundException, BusinessException, etc.), customizable error messages for localization, global exception handling middleware, and smart exclusion capabilities for specific endpoints or result types. Perfect for microservices, complex business workflows, and APIs requiring consistent client-side error handling. Supports .NET 9.0+ with minimal performance overhead and extensive debugging capabilities.
$ dotnet add package FS.AspNetCore.ResponseWrapperEnterprise-grade API response wrapper for ASP.NET Core - standardize your APIs with zero code changes.
Transform your raw controller responses into rich, metadata-enhanced API responses automatically. Add comprehensive error handling, request tracking, pagination support, and enterprise features without modifying existing code.
Problem: Your API returns inconsistent response formats, lacks proper error handling, and provides no request tracking or metadata.
Solution: Add one NuGet package and 2 lines of code - get enterprise-grade API responses automatically.
// Before
public async Task<User> GetUser(int id) => await _userService.GetUserAsync(id);
// After (no code changes needed!)
public async Task<User> GetUser(int id) => await _userService.GetUserAsync(id);
Automatic transformation:
{
"success": true,
"data": { "id": 1, "name": "John Doe" },
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2025-01-15T10:30:45.123Z",
"executionTimeMs": 42,
"path": "/api/users/1",
"method": "GET"
}
}
dotnet add package FS.AspNetCore.ResponseWrapper
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddResponseWrapper(); // 👈 Line 1
var app = builder.Build();
app.UseMiddleware<GlobalExceptionHandlingMiddleware>(); // 👈 Line 2 (optional but recommended)
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Your existing controllers now return wrapped responses automatically:
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
[HttpGet("{id}")]
public async Task<User> GetUser(int id)
{
var user = await _userService.GetUserAsync(id);
if (user == null)
throw new NotFoundException("User", id);
return user;
}
}
Success Response:
{
"success": true,
"data": { "id": 1, "name": "John Doe", "email": "john@example.com" },
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2025-01-15T10:30:45.123Z",
"executionTimeMs": 42
}
}
Error Response:
{
"success": false,
"data": null,
"message": "The requested item could not be found",
"statusCode": "NOT_FOUND",
"errors": ["User (123) was not found."],
"metadata": {
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2025-01-15T10:32:15.456Z"
}
}
builder.Services.AddResponseWrapper();
app.UseMiddleware<GlobalExceptionHandlingMiddleware>();
// Works automatically with ANY pagination library!
[HttpGet]
public async Task<PagedResult<Product>> GetProducts(int page = 1)
=> await _service.GetPagedAsync(page, 20);
public class LoginResult : IHasStatusCode, IHasMessage
{
public string Token { get; set; }
public string StatusCode { get; set; } = "LOGIN_SUCCESS";
public string Message { get; set; } = "Welcome back!";
}
// Install meta package
dotnet add package FS.AspNetCore.ResponseWrapper.Extensions
// One-line setup
builder.Services.AddResponseWrapperWithPreset(PresetType.Enterprise, "MyAPI");
app.UseResponseWrapperExtensions();
Install the all-in-one enterprise package:
dotnet add package FS.AspNetCore.ResponseWrapper.Extensions
Includes:
Quick Enterprise Setup:
// One line gets you everything
builder.Services.AddResponseWrapperWithPreset(PresetType.Enterprise, "MyAPI");
app.UseResponseWrapperExtensions();
See Enterprise Features Documentation for details.
builder.Services.AddResponseWrapper(options =>
{
// Enable/disable features
options.EnableExecutionTimeTracking = true;
options.EnablePaginationMetadata = true;
options.EnableCorrelationId = true;
// Exclude specific endpoints
options.ExcludedPaths = new[] { "/health", "/metrics" };
// Customize error messages
}, errorMessages =>
{
errorMessages.ValidationErrorMessage = "Please check your input";
errorMessages.NotFoundErrorMessage = "Item not found";
});
12 exception types with automatic error code extraction:
ValidationException - Input validation errors (400)NotFoundException - Resource not found (404)BusinessException - Business rule violations (400)ConflictException - Resource conflicts (409)UnauthorizedException - Authentication required (401)ForbiddenAccessException - Authorization failed (403)BadRequestException - Invalid requests (400)TimeoutException - Operation timeout (408)TooManyRequestsException - Rate limiting (429)ServiceUnavailableException - Service down (503)CustomHttpStatusException - Any custom status codeApplicationExceptionBase - Base for custom exceptionsAll exceptions include automatic error codes for client-side handling.
{
"success": true, // Operation outcome
"data": { ... }, // Your business data
"message": "...", // Optional message
"statusCode": "...", // Application status code
"errors": [...], // Error messages (if any)
"metadata": { // Request metadata
"requestId": "...", // Unique request ID
"timestamp": "...", // Response timestamp
"executionTimeMs": 42, // Execution time
"correlationId": "...", // Distributed tracing
"path": "/api/users", // Request path
"method": "GET", // HTTP method
"pagination": { ... }, // Pagination info (if applicable)
"additional": { ... } // Custom metadata
}
}
MIT License - see LICENSE file for details.
Contributions are welcome! Please read our Contributing Guide for details.
Made with ❤️ by Furkan Sarıkaya
Transform your ASP.NET Core APIs with enterprise-grade response wrapping. Install today and elevate your API development!