EnumCraft.Json
0.2.0-preview
dotnet add package EnumCraft.Json --version 0.2.0-preview
NuGet\Install-Package EnumCraft.Json -Version 0.2.0-preview
<PackageReference Include="EnumCraft.Json" Version="0.2.0-preview" />
<PackageVersion Include="EnumCraft.Json" Version="0.2.0-preview" />
<PackageReference Include="EnumCraft.Json" />
paket add EnumCraft.Json --version 0.2.0-preview
#r "nuget: EnumCraft.Json, 0.2.0-preview"
#:package EnumCraft.Json@0.2.0-preview
#addin nuget:?package=EnumCraft.Json&version=0.2.0-preview&prerelease
#tool nuget:?package=EnumCraft.Json&version=0.2.0-preview&prerelease
EnumCraft.Json
JSON serialization extensions for EnumCraft TypedEnum and TypedFlag instances
What is EnumCraft.Json?
A lightweight JSON serialization extension package for EnumCraft.Core that provides clean, structured JSON output for TypedEnum and TypedFlag instances.
✅ Simple JSON serialization for TypedEnum
✅ Enhanced serialization for TypedFlag with decomposed flags array
✅ Customizable output with JsonSerializerOptions
✅ Zero configuration - just add the package and use the extensions
✅ Multi-targeted - Works with .NET Framework 4.7.2+ and .NET Standard 2.0+
Installation
dotnet add package EnumCraft.Core
dotnet add package EnumCraft.Json
Quick Start
TypedEnum Serialization
using EnumCraft;
using EnumCraft.Json;
public class OrderStatus : TypedEnumInt<OrderStatus>
{
public static readonly OrderStatus Pending = new(1, "Pending", nameof(Pending));
public static readonly OrderStatus Confirmed = new(2, "Confirmed", nameof(Confirmed));
public static readonly OrderStatus Shipped = new(3, "Shipped", nameof(Shipped));
private OrderStatus(int id, string description, string code)
: base(id, description, code) { }
}
// Serialize to object
var status = OrderStatus.Pending;
var jsonObj = status.AsJsonObject();
// Returns: { id = 1, description = "Pending", code = "Pending" }
// Serialize to JSON string
string json = status.AsJsonString();
// Returns: {"id":1,"description":"Pending","code":"Pending"}
// With formatting
var options = new JsonSerializerOptions { WriteIndented = true };
string prettyJson = status.AsJsonString(options);
TypedFlag Serialization
using EnumCraft;
using EnumCraft.Json;
public class Permissions : TypedFlagInt<Permissions>
{
public static readonly Permissions None = new(0, "None", nameof(None));
public static readonly Permissions Read = new(1, "Read", nameof(Read));
public static readonly Permissions Write = new(2, "Write", nameof(Write));
public static readonly Permissions Execute = new(4, "Execute", nameof(Execute));
public static readonly Permissions All = new(7, "All", nameof(All));
private Permissions(int id, string description, string code)
: base(id, description, code) { }
}
// Single flag
var read = Permissions.Read;
var jsonObj = read.ToJsonObject();
// Returns: { id = 1, description = "Read", code = "Read" }
// Combined flags - includes decomposed flags array!
var readWrite = Permissions.Read | Permissions.Write;
var combinedObj = readWrite.ToJsonObject();
// Returns:
// {
// id = 3,
// description = "Read, Write",
// code = "Read | Write",
// flags = [
// { id = 1, description = "Read", code = "Read" },
// { id = 2, description = "Write", code = "Write" }
// ]
// }
// Serialize to JSON string
string json = readWrite.ToJsonString();
API Reference
TypedEnum Extensions
Available on all ITypedEnum<TSelf, TId> instances:
AsJsonObject()
object AsJsonObject<TSelf, TId>(this ITypedEnum<TSelf, TId> typedEnum)
Returns an anonymous object with id, description, and code properties.
Example:
var status = OrderStatus.Pending;
var obj = status.AsJsonObject();
// { id = 1, description = "Pending", code = "Pending" }
AsJsonString()
string AsJsonString<TSelf, TId>(
this ITypedEnum<TSelf, TId> typedEnum,
JsonSerializerOptions? options = null)
Returns a JSON string representation.
Example:
var json = OrderStatus.Pending.AsJsonString();
// {"id":1,"description":"Pending","code":"Pending"}
var options = new JsonSerializerOptions { WriteIndented = true };
var prettyJson = OrderStatus.Pending.AsJsonString(options);
TypedFlag Extensions
Available on all TypedFlag instances (use different method names to avoid conflicts):
ToJsonObject()
object ToJsonObject<TSelf, TId>(this ITypedEnum<TSelf, TId> typedEnum)
Returns an anonymous object with id, description, and code properties. For combined flags, includes a flags array with decomposed flag objects.
Example - Single Flag:
var read = Permissions.Read;
var obj = read.ToJsonObject();
// { id = 1, description = "Read", code = "Read" }
Example - Combined Flags:
var combo = Permissions.Read | Permissions.Write | Permissions.Execute;
var obj = combo.ToJsonObject();
// {
// id = 7,
// description = "Read, Write, Execute",
// code = "Read | Write | Execute",
// flags = [
// { id = 1, description = "Read", code = "Read" },
// { id = 2, description = "Write", code = "Write" },
// { id = 4, description = "Execute", code = "Execute" }
// ]
// }
ToJsonString()
string ToJsonString<TSelf, TId>(
this ITypedEnum<TSelf, TId> typedEnum,
JsonSerializerOptions? options = null)
Returns a JSON string representation with flags array for combined flags.
Example:
var combo = Permissions.Read | Permissions.Write;
var json = combo.ToJsonString();
// {"id":3,"description":"Read, Write","code":"Read | Write","flags":[...]}
Method Names: Why Different?
TypedEnum uses: AsJsonObject() and AsJsonString()
TypedFlag uses: ToJsonObject() and ToJsonString()
Why the difference?
Due to .NET Standard 2.0 compatibility constraints with IBitwiseOperators, TypedFlag extensions use different method names to avoid compilation issues while still providing the same functionality.
Usage is straightforward:
- For TypedEnum → use
As...methods - For TypedFlag → use
To...methods
Both provide clean JSON serialization!
Advanced Usage
Custom JSON Options
var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var json = OrderStatus.Pending.AsJsonString(options);
Using in APIs
[HttpGet("status/{id}")]
public IActionResult GetStatus(int id)
{
var status = OrderStatus.GetByID(id);
var jsonObj = status.AsJsonObject();
return Ok(jsonObj);
}
[HttpGet("permissions")]
public IActionResult GetPermissions()
{
var userPerms = Permissions.Read | Permissions.Write;
var jsonObj = userPerms.ToJsonObject();
return Ok(jsonObj);
}
Serializing Collections
var allStatuses = OrderStatus.GetAll();
var jsonArray = allStatuses.Select(s => s.AsJsonObject()).ToArray();
var json = JsonSerializer.Serialize(jsonArray);
Why Use EnumCraft.Json?
vs. Default ToString()
Default:
var status = OrderStatus.Pending;
var str = status.ToString();
// "Pending (1)" - not structured, not JSON
With EnumCraft.Json:
var json = status.AsJsonString();
// {"id":1,"description":"Pending","code":"Pending"} - clean, structured JSON
vs. Manual Serialization
Manual:
var obj = new { id = status.ID, description = status.Description };
var json = JsonSerializer.Serialize(obj);
With EnumCraft.Json:
var json = status.AsJsonString();
// One line, consistent across all TypedEnums
TypedFlag Benefits
Without EnumCraft.Json:
var combo = Permissions.Read | Permissions.Write;
var json = JsonSerializer.Serialize(combo);
// Just serializes the object - no flags array
With EnumCraft.Json:
var json = combo.ToJsonString();
// Includes decomposed flags array automatically!
// {"id":3,"flags":[{"id":1,...},{"id":2,...}]}
Framework Support
| Framework | Supported |
|---|---|
| .NET Framework 4.7.2+ | ✅ |
| .NET Standard 2.0+ | ✅ |
| .NET Core 3.1+ | ✅ |
| .NET 5+ | ✅ |
| .NET 6+ | ✅ |
| .NET 7+ | ✅ |
| .NET 8+ | ✅ |
Dependencies
This package requires:
- EnumCraft.Core (v0.1.2-preview or later)
- System.Text.Json (v4.7.2 or later)
- Microsoft.CSharp (v4.7.0 or later) - for .NET Standard 2.0 dynamic support
Related Packages
- EnumCraft.Core - Type-safe enumerations and flags
- EnumCraft.FeatureFlags - Feature flag system with tenant overrides
Common Patterns
API Response DTOs
public class OrderDto
{
public int OrderId { get; set; }
public object Status { get; set; } // Use object to hold JSON
public object Permissions { get; set; }
}
var dto = new OrderDto
{
OrderId = 123,
Status = OrderStatus.Confirmed.AsJsonObject(),
Permissions = userPerms.ToJsonObject()
};
return Ok(dto);
Logging
var status = OrderStatus.Pending;
_logger.LogInformation("Order status changed: {Status}", status.AsJsonString());
Database Storage
// Store as JSON in a text column
var jsonString = status.AsJsonString();
await SaveToDatabase(orderId, jsonString);
// Later, deserialize and lookup
var statusId = JsonDocument.Parse(jsonString).RootElement.GetProperty("id").GetInt32();
var status = OrderStatus.GetByID(statusId);
Best Practices
✅ DO
- Use
AsJsonObject()when you need the object for further manipulation - Use
AsJsonString()when you need the final JSON string - Use
ToJsonObject()for TypedFlags to get the flags array - Reuse
JsonSerializerOptionsinstances for performance
❌ DON'T
- Mix
As...andTo...methods inappropriately (use As for Enum, To for Flag) - Serialize directly without using these extensions (you lose the structured output)
- Create custom serializers when these extensions already do what you need
Troubleshooting
"Method not found" errors
Make sure you have:
using EnumCraft.Json;
at the top of your file.
TypedFlag doesn't show flags array
Make sure you're using ToJsonObject() / ToJsonString() (not AsJson...):
// ❌ Wrong
var json = myFlag.AsJsonString(); // Won't include flags array
// ✅ Correct
var json = myFlag.ToJsonString(); // Includes flags array
Documentation
For comprehensive documentation and examples:
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details
Author
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- EnumCraft.Core (>= 0.2.0-preview)
- Microsoft.CSharp (>= 4.7.0)
- System.Text.Json (>= 4.7.2)
-
net8.0
- EnumCraft.Core (>= 0.2.0-preview)
- Microsoft.CSharp (>= 4.7.0)
- System.Text.Json (>= 4.7.2)
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 |
|---|---|---|
| 0.2.0-preview | 29 | 2/24/2026 |
| 0.1.4-preview | 42 | 2/22/2026 |
| 0.1.3-preview | 47 | 2/19/2026 |
| 0.1.0-preview | 48 | 2/17/2026 |