JsonUnion 1.0.5

There is a newer version of this package available.
See the version list below for details.
dotnet add package JsonUnion --version 1.0.5
NuGet\Install-Package JsonUnion -Version 1.0.5
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="JsonUnion" Version="1.0.5" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add JsonUnion --version 1.0.5
#r "nuget: JsonUnion, 1.0.5"
#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.
// Install JsonUnion as a Cake Addin
#addin nuget:?package=JsonUnion&version=1.0.5

// Install JsonUnion as a Cake Tool
#tool nuget:?package=JsonUnion&version=1.0.5

JsonUnion

The simplest way for multiple JSON responses under a single request.

Combine the power the OneOf library with union-like returns of JSON responses.

How to install

Via tha Package Manager:

Install-Package JsonUnion

Via the .NET CLI

dotnet add package JsonUnion

Example 1 - Get the properties of a JSON node

The extension method is useful when a single endpoint returns JSON answers with different formats. In the following example, we assume a class named ResponseOk. We want to examine the properties of the JSON string before assigning it to a typed variable.

using System.Text.Json;
using System.Text.Json.Nodes;
using JsonUnion;

public class ResponseOk
{
    public int Prop1 { get; init; }
    public string? Prop2 { get; init; }
    public string? Prop3 { get; init; }
}
...

string contentScenario1 = """
    {
    "prop1": 10,
    "prop2": "n1"
    }
    """;


    //Case 1
    //Get only the properties of the JSON node, not the non-initialized properties of the instance.
    JsonNode? jsonNode1 = JsonNode.Parse(contentScenario1);
    //GetProperties is an extension method of JsonUnion library
    var properties = jsonNode1!.GetProperties()!; 
    foreach (string p in properties)
        Console.WriteLine(p);

    //will print:
    //prop1
    //prop2

Example 2 - Examine if a property of the JSON exists

For the same variable contentScenario1, we can get an IDictionary, which allows examination of the existence of a specific property. By ensuring that a property exists, we can assume that the correct JSON format is returned, because the parse is completed.

//Case 2
JsonNode? jsonNode1 = JsonNode.Parse(contentScenario1);

//ToDictionary is an extension method of JsonUnion library
var d = jsonNode1!.ToDictionary();
Console.WriteLine(d!.ContainsKey("prop1"));

//will print:
//true

Example 2 - Return one of multiple types avoiding throwing exceptions

The Deserialize method of the JsonSerializer throws an exception when the expected format is problematic. This is where the JsonUnion comes into play. In the following example, we assume that there are 2 possible return types. The Deserialize method of the JsonUnionSerializer static class returns a OneOf instance.

More specifically this instance is of type: OneOf.OneOf<ResponseOk?, ResponseOk2?, Error?>? The Error type is a simpe record type that encapsulates a single error message in case for parse exceptions only. Note that the content argument and at least one of propertyIndentifierForFirstType or propertyIdentifierForSecondType must be non empty or else the call is meaningless.

The propertyIndentifierForFirstType arguments is the property identifier of the first candidate type (in this case of type ResponseOk). It is assumed that this property is not also contained in the ResponseOk2. Alternatively we can pass the propertyIdentifierForSecondType argument instead.

public class ResponseOk
{
    public int Prop1 { get; init; }
    public string? Prop2 { get; init; }
    public string? Prop3 { get; init; }
}
public class ResponseOk2
{
    public string? Message { get; init; }
    public int Code { get; init; }
}
...

string contentScenario1 = """
        {
        "prop1": 10,
        "prop2": "n1"
        }
        """;

string contentScenario2 = """
        {
        "message": "Alternative stuff",
        "code": 100
        }
        """;

JsonSerializerOptions o = new() { PropertyNameCaseInsensitive = true };

var response1 = JsonUnionSerializer.Deserialize<ResponseOk, ResponseOk2>(
    content: contentScenario1,
    propertyIndentifierForFirstType: "prop1",
    throwExceptionForBadFormat: false,
    options: o);

if (response1.HasValue)
{
    var r = response1.Value;
    r.Switch(
        ok => Console.WriteLine($"{ok!.Prop1}, {ok!.Prop2}"),
        ok2 => Console.WriteLine($"{ok2!.Message}, {ok2.Code}"),
        error => Console.WriteLine($"{error!.Message}")
        );
}
//will print (for contentScenario1):
//10, n1

//will print (for contentScenario2):
//Alternative stuff, 100


//OR: here is alternative way of handling the response
if (response1.HasValue)
{
    var r = response1.Value;
    if (r.IsT0) //i.e. ResponseOk
    {
        ResponseOk ok = r.AsT0!;
        Console.WriteLine($"{ok.Prop1}, {ok.Prop2}");
    }
    else if (r.IsT1) //i.e. ResponseOk2
    {
        ResponseOk2 ok2 = r.AsT1!;
        Console.WriteLine($"{ok2.Message}, {ok2.Code}");
    }
    else //Error
    {
        Error error = r.AsT2!;
        Console.WriteLine($"{error.Message}");
    }
}


Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0

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.11 105 3/1/2024
1.0.10 159 7/21/2023
1.0.8 149 7/20/2023
1.0.7 131 7/20/2023
1.0.6 140 7/20/2023
1.0.5 127 7/20/2023
1.0.4 117 7/20/2023