Setup and Configuration
Complete guide to setting up and configuring EasyMessages in ASP.NET Core applications.
Table of Contents
- Installation
- Basic Setup
- Configuration Methods
- Configuration Options
- Environment-Specific Configuration
- Advanced Setup
- Troubleshooting
Installation
Package Installation
Install the package via NuGet:
# .NET CLI
dotnet add package RecurPixel.EasyMessages --version 1.0.0
# Package Manager Console
Install-Package RecurPixel.EasyMessages -Version 1.0.0
No DI registration is required — the package works without any AddEasyMessages() call.
Project File Reference
Your .csproj file should include:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RecurPixel.EasyMessages" Version="1.0.0" />
</ItemGroup>
</Project>
Supported .NET Versions: .NET 5.0 - 10.0
Basic Setup
Minimal Setup
Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
No additional registration is needed. Import RecurPixel.EasyMessages in your controllers and use the Msg facades directly.
Controller Usage
UsersController.cs:
using Microsoft.AspNetCore.Mvc;
using RecurPixel.EasyMessages;
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly ILogger<UsersController> _logger;
public UsersController(ILogger<UsersController> logger)
{
_logger = logger;
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var user = _userRepository.FindById(id);
if (user == null)
{
var notFound = Msg.Crud.NotFound("User")
.WithMetadata("userId", id)
.Log(_logger);
return StatusCode(notFound.HttpStatusCode ?? 404, notFound.ToJsonObject());
}
var ok = Msg.Crud.Retrieved("User").WithData(user);
return StatusCode(ok.HttpStatusCode ?? 200, ok.ToJsonObject());
}
}
Minimal API Usage
Program.cs:
using RecurPixel.EasyMessages;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/api/users/{id}", (int id, ILogger<Program> logger) =>
{
var user = userRepository.FindById(id);
if (user == null)
{
var notFound = Msg.Crud.NotFound("User").WithMetadata("userId", id).Log(logger);
return Results.Json(notFound.ToJsonObject(), statusCode: notFound.HttpStatusCode ?? 404);
}
var ok = Msg.Crud.Retrieved("User").WithData(user);
return Results.Json(ok.ToJsonObject(), statusCode: ok.HttpStatusCode ?? 200);
});
app.Run();
Configuration Methods
EasyMessages formatter behavior can be configured at startup or inline:
1. appsettings.json (Custom Messages Storage)
Use appsettings to configure the custom messages file path:
appsettings.json:
{
"EasyMessages": {
"Storage": {
"CustomMessagesPath": "messages/custom.json"
}
}
}
Load it at startup:
Program.cs:
var customPath = builder.Configuration["EasyMessages:Storage:CustomMessagesPath"];
if (!string.IsNullOrEmpty(customPath))
{
MessageRegistry.LoadCustomMessages(customPath);
}
2. FormatterConfiguration
Configure formatter options globally using FormatterConfiguration.Configure():
Program.cs:
using RecurPixel.EasyMessages.Configuration;
FormatterConfiguration.Configure(options =>
{
options.IncludeTimestamp = true;
options.IncludeMetadata = true;
options.IncludeNullFields = false;
});
3. Inline per Message
Override options inline per-call:
var json = Msg.Crud.Created("User")
.WithData(user)
.ToJson(options => options.IncludeTimestamp = false);
Configuration Options
FormatterOptions
Controls which fields are included in formatted output (JSON, XML, etc.).
public class FormatterOptions
{
public bool IncludeTimestamp { get; set; } = true;
public bool IncludeCorrelationId { get; set; } = true;
public bool IncludeHttpStatusCode { get; set; } = true;
public bool IncludeMetadata { get; set; } = true;
public bool IncludeData { get; set; } = true;
public bool IncludeParameters { get; set; } = true;
public bool IncludeHint { get; set; } = true;
public bool IncludeNullFields { get; set; } = false;
}
Use Cases:
- Production: Minimal fields (performance)
- Development: All fields (debugging)
- API Clients: Essential fields only
- Logging: Verbose fields
Environment-Specific Configuration
Development Environment
Program.cs:
if (builder.Environment.IsDevelopment())
{
FormatterConfiguration.Configure(options =>
{
options.IncludeTimestamp = true;
options.IncludeMetadata = true;
options.IncludeNullFields = true;
});
}
Production Environment
Program.cs:
if (builder.Environment.IsProduction())
{
FormatterConfiguration.Configure(options =>
{
options.IncludeTimestamp = false;
options.IncludeMetadata = false;
options.IncludeNullFields = false;
});
}
Using Environment Variables
You can also configure via environment variables (loaded by ASP.NET Core automatically):
EasyMessages__Storage__CustomMessagesPath=messages/custom.json
Then in Program.cs:
var customPath = builder.Configuration["EasyMessages:Storage:CustomMessagesPath"];
if (!string.IsNullOrEmpty(customPath))
{
MessageRegistry.LoadCustomMessages(customPath);
}
Advanced Setup
Custom Messages
Load custom messages from a JSON file:
MessageRegistry.LoadCustomMessages("messages/custom.json");
Custom Message File Format:
{
"CUSTOM_001": {
"type": "Success",
"title": "Payment Successful",
"description": "Payment of ${amount} was processed successfully.",
"httpStatusCode": 200
},
"CUSTOM_002": {
"type": "Error",
"title": "Payment Failed",
"description": "Payment failed: {reason}",
"httpStatusCode": 402
}
}
Usage:
var msg = Msg.Custom("CUSTOM_001").WithParams(new { amount = "$50.00" });
return StatusCode(msg.HttpStatusCode ?? 200, msg.ToJsonObject());
Custom Interceptors
Register custom interceptors programmatically:
MessageRegistry.AddInterceptor(new AuditLoggingInterceptor());
MessageRegistry.AddInterceptor(new PerformanceTrackingInterceptor());
Troubleshooting
Issue: Custom Messages Not Loading
Symptoms: Custom message codes not found at runtime
Solution:
var path = "messages/custom.json";
var fullPath = Path.GetFullPath(path);
Console.WriteLine($"Loading messages from: {fullPath}");
Console.WriteLine($"File exists: {File.Exists(fullPath)}");
MessageRegistry.LoadCustomMessages(path);
var codes = MessageRegistry.GetAllCodes();
Console.WriteLine($"Loaded message codes: {string.Join(", ", codes)}");
Issue: HttpStatusCode is null
Symptoms: msg.HttpStatusCode returns null
Solution: Use a fallback value:
return StatusCode(msg.HttpStatusCode ?? 200, msg.ToJsonObject());
Issue: Log messages not appearing
Symptoms: .Log(_logger) calls produce no output
Causes:
- Logger category filtered by log level
- Message type below minimum log level
Solution:
{
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}
Next Steps
- Configuration Presets - Pre-built environment configurations
- API Response Patterns - REST API response patterns
- Logging Integration - Advanced logging strategies
Questions? Ask in Discussions