CodeMode.ResponseModel
1.0.0
dotnet add package CodeMode.ResponseModel --version 1.0.0
NuGet\Install-Package CodeMode.ResponseModel -Version 1.0.0
<PackageReference Include="CodeMode.ResponseModel" Version="1.0.0" />
<PackageVersion Include="CodeMode.ResponseModel" Version="1.0.0" />
<PackageReference Include="CodeMode.ResponseModel" />
paket add CodeMode.ResponseModel --version 1.0.0
#r "nuget: CodeMode.ResponseModel, 1.0.0"
#:package CodeMode.ResponseModel@1.0.0
#addin nuget:?package=CodeMode.ResponseModel&version=1.0.0
#tool nuget:?package=CodeMode.ResponseModel&version=1.0.0
CodeMode.ResponseModel
A comprehensive and feature-rich response model package for .NET applications. Provides standardized API response handling with generic/non-generic support, HTTP status code mapping, fluent API, metadata support, validation errors, pagination, extension methods, and automatic timestamp tracking.
🚀 Features
- ✅ Generic & Non-Generic Responses - Support for both
ResponseandResponse<T> - ✅ HTTP Status Code Mapping - Automatic mapping to standard HTTP status codes
- ✅ Fluent API - Chainable methods for elegant response building
- ✅ Metadata Support - Attach additional data using dictionary-based metadata
- ✅ Timestamp Tracking - Automatic UTC timestamp for all responses
- ✅ Validation Errors - Built-in support for validation error handling
- ✅ Custom Errors - Flexible custom error model
- ✅ Pagination Support -
PagedResponse<T>for paginated data - ✅ Extension Methods - Rich set of extension methods for functional programming
- ✅ Exception Details - Debug mode support for exception details
- ✅ Result Pattern -
IsSuccessandIsFailureproperties - ✅ Type Safety - Strongly typed responses with full IntelliSense support
📦 Installation
NuGet Package Manager
Install-Package CodeMode.ResponseModel
.NET CLI
dotnet add package CodeMode.ResponseModel
PackageReference
<PackageReference Include="CodeMode.ResponseModel" Version="2.0.0" />
🎯 Quick Start
Basic Usage
using CodeMode.ResponseModel.Concreate.ResponceModel;
// Success response
var response = Response<User>.Success(user, "User created successfully");
// Error response
var response = Response<User>.Error("User not found");
// Not found response
var response = Response<User>.NotFound("User with ID 123 not found");
// Validation error
var errors = new List<CustomValidationError>
{
new CustomValidationError("Email", "Email is required"),
new CustomValidationError("Password", "Password must be at least 8 characters")
};
var response = Response<User>.ValidationError(errors);
Fluent API
var response = Response<User>.Success(user)
.WithMessage("User created successfully")
.WithMetadata("requestId", Guid.NewGuid())
.WithMetadata("executionTime", "150ms")
.WithMetadata("server", "API-01");
ASP.NET Core Integration
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;
[HttpPost]
public IActionResult CreateUser(CreateUserDto dto)
{
var response = _userService.CreateUser(dto);
return StatusCode(response.HttpStatusCode, response);
}
[HttpGet("{id}")]
public IActionResult GetUser(int id)
{
var response = _userService.GetUser(id);
if (response.IsSuccess)
return Ok(response);
return StatusCode(response.HttpStatusCode, response);
}
}
📖 Documentation
Response Types
1. Success Responses
// With data and message
var response = Response<User>.Success(user, "Operation completed successfully");
// With metadata
var response = Response<User>.Success(user, "User created", new Dictionary<string, object>
{
["userId"] = user.Id,
["createdAt"] = DateTime.UtcNow
});
2. Error Responses
// Bad Request (400)
Response<User>.BadRequest("Invalid input data");
// Unauthorized (401)
Response<User>.Unauthorized("Invalid credentials");
// Forbidden (403)
Response<User>.Forbidden("You don't have permission to access this resource");
// Not Found (404)
Response<User>.NotFound("User not found");
// Conflict (409)
Response<User>.Conflict("User already exists");
// Validation Error (422)
Response<User>.ValidationError(validationErrors);
// Internal Server Error (500)
Response<User>.Error("An unexpected error occurred");
Response<User>.InternalServerError("Database connection failed");
3. Validation Errors
var validationErrors = new List<CustomValidationError>
{
new CustomValidationError("Email", "Email is required"),
new CustomValidationError("Email", "Email format is invalid"),
new CustomValidationError("Password", "Password must be at least 8 characters"),
new CustomValidationError("Password", "Password must contain at least one uppercase letter")
};
var response = Response<User>.ValidationError(validationErrors);
4. Custom Errors
var customErrors = new List<CustomError>
{
new CustomError("DB_CONNECTION_FAILED", "Unable to connect to database"),
new CustomError("CACHE_UNAVAILABLE", "Redis cache is not responding")
};
var response = Response.Error(customErrors);
Pagination Support
public PagedResponse<List<User>> GetUsers(int pageIndex, int pageSize)
{
var users = _userRepository.GetUsers(pageIndex, pageSize);
var totalCount = _userRepository.GetTotalCount();
return PagedResponse<List<User>>
.Create(users, pageIndex, pageSize, totalCount)
.WithMessage("Users retrieved successfully")
.WithMetadata("cacheHit", true);
}
// Response includes:
// - Data (List<User>)
// - PageIndex (current page)
// - PageSize (items per page)
// - TotalCount (total items)
// - TotalPages (calculated)
// - HasPreviousPage (boolean)
// - HasNextPage (boolean)
Fluent API Methods
var response = Response<User>.Success(user)
.WithMessage("Custom message")
.WithMetadata("key", "value")
.WithMetadata(new Dictionary<string, object>
{
["requestId"] = Guid.NewGuid(),
["timestamp"] = DateTime.UtcNow
})
.WithData(updatedUser);
#if DEBUG
response.WithException(exception);
#endif
Extension Methods
OnSuccess & OnFailure
response
.OnSuccess(user =>
{
_logger.LogInformation($"User {user.Name} created successfully");
_eventBus.Publish(new UserCreatedEvent(user));
})
.OnFailure(resp =>
{
_logger.LogError($"Failed to create user: {resp.Message}");
});
Map - Transform Response Data
Response<UserDto> dtoResponse = userResponse.Map(user => new UserDto
{
Id = user.Id,
Name = user.Name,
Email = user.Email
});
Bind - Monad Pattern
public Response<Order> CreateOrder(int userId)
{
return GetUser(userId)
.Bind(user => ValidateUser(user))
.Bind(user => CreateOrderForUser(user));
}
Validation Helpers
if (response.HasValidationErrors())
{
var firstError = response.GetFirstValidationError();
Console.WriteLine($"Validation failed: {firstError}");
}
if (response.HasErrors())
{
var firstError = response.GetFirstError();
Console.WriteLine($"Error: {firstError}");
}
Metadata Helpers
if (response.HasMetadata("requestId"))
{
var requestId = response.GetMetadata<Guid>("requestId");
_logger.LogInformation($"Request ID: {requestId}");
}
Combine Responses
var combinedResponse = firstResponse.Combine(secondResponse);
// Returns first failure, or first success if both succeed
Response Properties
public class Response<T>
{
// Data
public T Data { get; set; }
// Status
public ResponseStatusCode ResponseStatusCode { get; set; }
public int HttpStatusCode { get; } // Auto-mapped (200, 400, 401, 404, etc.)
public bool IsSuccess { get; } // True if ResponseStatusCode == Success
public bool IsFailure { get; } // !IsSuccess
// Message & Errors
public string Message { get; set; }
public IEnumerable<CustomValidationError> ValidationErrors { get; set; }
public IEnumerable<CustomError> Errors { get; set; }
// Metadata & Tracking
public Dictionary<string, object> Metadata { get; set; }
public DateTime Timestamp { get; set; } // UTC, auto-set
// Debug Info (only in DEBUG builds)
#if DEBUG
public string ExceptionMessage { get; set; }
public string StackTrace { get; set; }
#endif
}
HTTP Status Code Mapping
| ResponseStatusCode | HTTP Status Code | Description |
|---|---|---|
| Success | 200 | Request succeeded |
| BadRequest | 400 | Invalid request data |
| Unauthorized | 401 | Authentication required |
| Forbidden | 403 | Insufficient permissions |
| NotFound | 404 | Resource not found |
| Conflict | 409 | Resource conflict |
| ValidationError | 422 | Validation failed |
| Error | 500 | Internal server error |
| InternalServerError | 500 | Internal server error |
🔧 Advanced Usage
Service Layer Pattern
public interface IUserService
{
Response<User> GetUser(int id);
Response<User> CreateUser(CreateUserDto dto);
PagedResponse<List<User>> GetUsers(int pageIndex, int pageSize);
}
public class UserService : IUserService
{
private readonly IUserRepository _repository;
private readonly IValidator<CreateUserDto> _validator;
public Response<User> CreateUser(CreateUserDto dto)
{
// Validate
var validationResult = _validator.Validate(dto);
if (!validationResult.IsValid)
{
var errors = validationResult.Errors
.Select(e => new CustomValidationError(e.PropertyName, e.ErrorMessage))
.ToList();
return Response<User>.ValidationError(errors);
}
try
{
// Check for duplicates
if (_repository.EmailExists(dto.Email))
{
return Response<User>.Conflict($"User with email {dto.Email} already exists");
}
// Create user
var user = _repository.Create(dto);
return Response<User>.Success(user, "User created successfully")
.WithMetadata("userId", user.Id)
.WithMetadata("createdAt", DateTime.UtcNow);
}
catch (Exception ex)
{
#if DEBUG
return Response<User>.Error(ex);
#else
return Response<User>.Error("An error occurred while creating the user");
#endif
}
}
}
Middleware Integration
public class ResponseFormatterMiddleware
{
private readonly RequestDelegate _next;
public async Task InvokeAsync(HttpContext context)
{
var originalBodyStream = context.Response.Body;
using (var responseBody = new MemoryStream())
{
context.Response.Body = responseBody;
await _next(context);
context.Response.Body = originalBodyStream;
responseBody.Seek(0, SeekOrigin.Begin);
var responseText = await new StreamReader(responseBody).ReadToEndAsync();
// Add global metadata
var response = JsonSerializer.Deserialize<Response>(responseText);
if (response != null)
{
response.Metadata["serverId"] = Environment.MachineName;
response.Metadata["apiVersion"] = "v1";
var modifiedResponse = JsonSerializer.Serialize(response);
await context.Response.WriteAsync(modifiedResponse);
}
}
}
}
Unit Testing
[Fact]
public void CreateUser_ValidData_ReturnsSuccess()
{
// Arrange
var dto = new CreateUserDto { Name = "Test", Email = "test@test.com" };
// Act
var response = _userService.CreateUser(dto);
// Assert
Assert.True(response.IsSuccess);
Assert.NotNull(response.Data);
Assert.Equal("User created successfully", response.Message);
Assert.Equal(200, response.HttpStatusCode);
}
[Fact]
public void CreateUser_DuplicateEmail_ReturnsConflict()
{
// Arrange
var dto = new CreateUserDto { Name = "Test", Email = "existing@test.com" };
// Act
var response = _userService.CreateUser(dto);
// Assert
Assert.False(response.IsSuccess);
Assert.True(response.IsFailure);
Assert.Equal(409, response.HttpStatusCode);
Assert.Contains("already exists", response.Message);
}
📝 Best Practices
Always use factory methods instead of constructors:
✅ Response<User>.Success(user) ❌ new Response<User>(ResponseStatusCode.Success, user)Use fluent API for complex responses:
return Response<User>.Success(user) .WithMessage("User created") .WithMetadata("requestId", requestId);Check success before accessing data:
if (response.IsSuccess) { var user = response.Data; }Use extension methods for cleaner code:
response .OnSuccess(user => NotifyUser(user)) .OnFailure(resp => LogError(resp.Message));Leverage metadata for tracing:
return Response<User>.Success(user) .WithMetadata("requestId", HttpContext.TraceIdentifier) .WithMetadata("executionTime", stopwatch.ElapsedMilliseconds);
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🔗 Links
📧 Support
If you encounter any issues or have questions, please open an issue on GitHub.
Made with ❤️ by CodeMode Team
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 111 | 1/27/2026 |