'Convert object to System.Text.Json.JsonElement

Let's say I have an object of type:

public class MyClass
{
    public string Data { get; set; }
}

And I need to convert it to System.Text.Json.JsonElement. The only way I found is:

var json = JsonSerializer.Serialize(new MyClass { Data = "value" });

using var document = JsonDocument.Parse(json);

var jsonElement = document.RootElement;

Seems strange that I have to serialize it first and then parse it. Is there a better approach for this?

Previously I was using JObject from Newtonsoft.Json and I could do it like this:

var jobject = JObject.FromObject(new MyClass { Data = "value" });


Solution 1:[1]

dbc's answer is a good start, but not enough if the object value is already a json string! Moreover, the type is not used in his code.

Thus I propose the following improved version:

    public static JsonDocument JsonDocumentFromObject(object value, JsonSerializerOptions options = null)
    {
        if (value is string valueStr)
        {
            try { return JsonDocument.Parse(valueStr); }
            catch {}
        }

        byte[] bytes = JsonSerializer.SerializeToUtf8Bytes(value, options);
        return JsonDocument.Parse(bytes);
    }

    public static JsonElement JsonElementFromObject(object value, JsonSerializerOptions options = null)
    {
        JsonElement result;
        using (JsonDocument doc = JsonDocumentFromObject(value, options))
        {
            result = doc.RootElement.Clone();
        }
        return result;
    }

with the following unit test (xUnit):

    [Fact()]
    public void JsonElementFromObjectTest()
    {
        object o = new
        {
            id = "myId",
            timestamp = DateTime.UtcNow,
            valid = true,
            seq = 1
        };

        JsonElement element1 = JsonSerializerExtension.JsonElementFromObject(o);
        Assert.Equal(JsonValueKind.Object, element1.ValueKind);
        string oStr1 = element1.GetRawText();
        Assert.NotNull(oStr1);

        JsonElement element2 = JsonSerializerExtension.JsonElementFromObject(oStr1);
        Assert.Equal(JsonValueKind.Object, element2.ValueKind);
        string oStr2 = element2.GetRawText();
        Assert.NotNull(oStr2);

        Assert.Equal(oStr1, oStr2);
    }

without the direct try Parse, element2 is a JsonValueKind.String and oStr2 contains the not escaped unicode characters, thus being an invalid Json string.

Solution 2:[2]

A slick approach in .NET 5 would be:

private JsonElement JsonElementFromObject(object value)
{
    var jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(value, new JsonSerializerOptions());
    using var doc = JsonDocument.Parse(jsonUtf8Bytes);
    return doc.RootElement.Clone();
}

Steps:

  1. Convert the value into a JSON string, encoded as UTF-8 bytes (SerializeToUtf8Bytes).
  2. Parse the JSON string (JsonDocument.Parse).
  3. Return the root element.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 EricBDev
Solution 2