System.Text.Json.JsonElement ToObject workaround

丶灬走出姿态 提交于 2019-12-23 11:05:09

问题


I want to know the equivalent of the ToObject<>() method in Json.NET for System.Text.Json.

Using Json.NET you can use any JToken and convert it to a class. EG:

var str = ""; // some json string
var jObj = JObject.Parse(str);
var myClass = jObj["SomeProperty"].ToObject<SomeClass>();

How would we be able to do this with .NET Core 3's new System.Text.Json

var str = ""; // some json string
var jDoc = JsonDocument.Parse(str);
var myClass = jDoc.RootElement.GetProperty("SomeProperty"). <-- now what??

Initially I was thinking I'd just convert the JsonElement that is returned in jDoc.RootElement.GetPRoperty("SomeProperty") to a string and then deserialize that string. But I feel that might not be the most efficient method, and I can't really find documentation on doing it another way.


回答1:


I came across the same issue, so I wrote some extension methods which work fine for now. It would be nice if they provided this as built in to avoid the additional allocation to a string.

public static T ToObject<T>(this JsonElement element)
{
    var json = element.GetRawText();
    return JsonSerializer.Deserialize<T>(json);
}
public static T ToObject<T>(this JsonDocument document)
{
    var json = document.RootElement.GetRawText();
    return JsonSerializer.Deserialize<T>(json);
}

Then use as follows:

jDoc.RootElement.GetProperty("SomeProperty").ToObject<SomeClass>();



回答2:


There is an open enhancement about this, currently targeted for System.Text.Json - 3.0:

  • We should be able serialize and serialize from DOM #42056.

In the interim you may get better performance by writing to an intermediate byte buffer rather than to a string, since both JsonDocument and Utf8JsonReader work directly with byte spans rather than strings or char spans:

public static partial class JsonExtensions
{
    public static T ToObject<T>(this JsonElement element, JsonSerializerOptions options = null)
    {
        var bufferWriter = new ArrayBufferWriter<byte>();
        using (var writer = new Utf8JsonWriter(bufferWriter))
            element.WriteTo(writer);
        return JsonSerializer.Deserialize<T>(bufferWriter.WrittenSpan, options);
    }

    public static T ToObject<T>(this JsonDocument document, JsonSerializerOptions options = null)
    {
        if (document == null)
            throw new ArgumentNullException(nameof(document));
        return document.RootElement.ToObject<T>(options);
    }       
}

Demo fiddle here.



来源:https://stackoverflow.com/questions/58138793/system-text-json-jsonelement-toobject-workaround

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!