EnumCraft.Json 0.2.0-preview

This is a prerelease version of EnumCraft.Json.
dotnet add package EnumCraft.Json --version 0.2.0-preview
                    
NuGet\Install-Package EnumCraft.Json -Version 0.2.0-preview
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EnumCraft.Json" Version="0.2.0-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EnumCraft.Json" Version="0.2.0-preview" />
                    
Directory.Packages.props
<PackageReference Include="EnumCraft.Json" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EnumCraft.Json --version 0.2.0-preview
                    
#r "nuget: EnumCraft.Json, 0.2.0-preview"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EnumCraft.Json@0.2.0-preview
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EnumCraft.Json&version=0.2.0-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=EnumCraft.Json&version=0.2.0-preview&prerelease
                    
Install as a Cake Tool

EnumCraft.Json

JSON serialization extensions for EnumCraft TypedEnum and TypedFlag instances

NuGet License: MIT

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


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 JsonSerializerOptions instances for performance

❌ DON'T

  • Mix As... and To... 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

BjorkquistBuilds
GitHub | NuGet

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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