LightResults.Extensions.Json
9.0.1
Prefix Reserved
dotnet add package LightResults.Extensions.Json --version 9.0.1
NuGet\Install-Package LightResults.Extensions.Json -Version 9.0.1
<PackageReference Include="LightResults.Extensions.Json" Version="9.0.1" />
<PackageVersion Include="LightResults.Extensions.Json" Version="9.0.1" />
<PackageReference Include="LightResults.Extensions.Json" />
paket add LightResults.Extensions.Json --version 9.0.1
#r "nuget: LightResults.Extensions.Json, 9.0.1"
#:package LightResults.Extensions.Json@9.0.1
#addin nuget:?package=LightResults.Extensions.Json&version=9.0.1
#tool nuget:?package=LightResults.Extensions.Json&version=9.0.1
LightResults Extensions
Extensions for LightResults, an extremely light and modern Operation Result Pattern library for .NET.
Json
Provides System.Text.Json converters for serializing Result
and Result<TValue>
types to JSON.
Documentation
Make sure to read the docs for the full API.
JSON Converters
This package provides JSON converters for serializing Result
and Result<TValue>
types using System.Text.Json. The converters support serialization only, as Result types cannot be reliably deserialized without losing data.
Provided Converters:
ResultJsonConverter
- SerializesResult
(non-generic) typesResultJsonConverter<TValue>
- SerializesResult<TValue>
typesResultJsonConverterFactory
- Factory that automatically selects the appropriate converter
Setup
Add the converter factory to your JsonSerializerOptions:
using System.Text.Json;
using LightResults.Extensions.Json;
var options = new JsonSerializerOptions
{
Converters =
{
new ResultJsonConverterFactory()
}
};
For ASP.NET Core applications, configure in Program.cs
:
using LightResults.Extensions.Json;
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.Converters.Add(new ResultJsonConverterFactory());
});
var app = builder.Build();
Usage Examples
Serializing Success Results
using System.Text.Json;
using LightResults.Extensions.Json;
var options = new JsonSerializerOptions
{
Converters = { new ResultJsonConverterFactory() }
};
// Success without value
var result = Result.Success();
var json = JsonSerializer.Serialize(result, options);
// Output: {"IsSuccess":true}
// Success with value
var resultWithValue = Result.Success(42);
var jsonWithValue = JsonSerializer.Serialize(resultWithValue, options);
// Output: {"IsSuccess":true,"Value":42}
// Success with complex object
var user = new { Id = 1, Name = "John Doe" };
var userResult = Result.Success(user);
var userJson = JsonSerializer.Serialize(userResult, options);
// Output: {"IsSuccess":true,"Value":{"Id":1,"Name":"John Doe"}}
Serializing Failure Results
// Simple failure
var failureResult = Result.Failure("Something went wrong");
var failureJson = JsonSerializer.Serialize(failureResult, options);
// Output: {"IsSuccess":false,"Errors":[{"$type":"LightResults.Error","Message":"Something went wrong"}]}
// Failure with metadata
var metadata = new Dictionary<string, object?> { { "ErrorCode", 404 } };
var failureWithMetadata = Result.Failure("Not found", metadata);
var metadataJson = JsonSerializer.Serialize(failureWithMetadata, options);
// Output: {"IsSuccess":false,"Errors":[{"$type":"LightResults.Error","Message":"Not found","Metadata":{"ErrorCode":{"$type":"System.Int32","Value":404}}}]}
// Failure with exception
try
{
throw new InvalidOperationException("Invalid operation");
}
catch (Exception ex)
{
var exceptionResult = Result.Failure("Operation failed", ex);
var exceptionJson = JsonSerializer.Serialize(exceptionResult, options);
// Output includes exception details in metadata
}
API Responses
Perfect for API responses that need to communicate both success/failure state and associated data:
// API Controller example
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
[HttpGet("{id}")]
public async Task<IActionResult> GetUser(int id)
{
var result = await userService.GetUserAsync(id);
// Result will be automatically serialized with proper JSON structure
return result.IsSuccess() ? Ok(result) : BadRequest(result);
}
}
// Success response JSON:
// {"IsSuccess":true,"Value":{"Id":1,"Name":"John Doe","Email":"john@example.com"}}
// Failure response JSON:
// {"IsSuccess":false,"Errors":[{"$type":"LightResults.Error","Message":"User not found"}]}
Working with Collections
// Collection of results
var results = new[]
{
Result.Success("First"),
Result.Failure("Second failed"),
Result.Success("Third")
};
var collectionJson = JsonSerializer.Serialize(results, options);
// Each result in the array will be properly serialized
// Result containing a collection
var items = new[] { "item1", "item2", "item3" };
var collectionResult = Result.Success(items);
var json = JsonSerializer.Serialize(collectionResult, options);
// Output: {"IsSuccess":true,"Value":["item1","item2","item3"]}
JSON Structure
The converters produce a consistent JSON structure:
Success Result:
{
"IsSuccess": true,
"Value": <serialized_value> // Only present for Result<TValue>
}
Failure Result:
{
"IsSuccess": false,
"Errors": [
{
"$type": "LightResults.Error",
"Message": "Error message",
"Metadata": {
"Key": {
"$type": "System.String",
"Value": "metadata_value"
}
}
}
]
}
Exception Handling: When an exception is stored in error metadata, it's serialized with its message and stack trace:
{
"$type": "System.InvalidOperationException",
"Message": "Operation is not valid due to the current state of the object.",
"StackTrace": "stack_trace_here"
}
Limitations
- Deserialization not supported: The converters only support serialization. Result types cannot be reliably deserialized without potential data loss
- Type information: The JSON includes type discriminators (
$type
) to preserve type information during serialization - Metadata serialization: Complex objects in metadata are serialized with their full type information
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 is compatible. 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. |
-
net6.0
- LightResults (>= 9.0.5)
-
net7.0
- LightResults (>= 9.0.5)
- Microsoft.NET.ILLink.Tasks (>= 9.0.7)
-
net8.0
- LightResults (>= 9.0.5)
- Microsoft.NET.ILLink.Tasks (>= 9.0.7)
-
net9.0
- LightResults (>= 9.0.5)
- Microsoft.NET.ILLink.Tasks (>= 9.0.7)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.