Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

c# - How can I access properties of dynamic object deserialized from a string using System.Test.Json?

using System.Text.Json;
using System.Text.Json.Serialization;

public static dynamic StringToObject(string str) {
    dynamic JsonObjectFromString = JsonSerializer.Deserialize<dynamic>(str);
    System.Console.WriteLine(JsonObjectFromString) // this line show correct json object with a correct type
    System.Console.WriteLine(JsonObjectFromString["cookies"]) // this line will error
    return JsonObjectFromString;
}

Basically when I try to access any property of dynamically deserialized object, my program errors. Is there any way to use JsonSerializer.Deserialize dynamically?

The string is basically from httpbin.

{
  "cookies": {}
}

Btw this doesn't happen with NewtonSoft.Json.

Error:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The best overloaded method match for 'System.Text.Json.JsonElement.this[int]' has some invalid arguments
         at CallSite.Target(Closure , CallSite , Object , String )
         at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
         at myNamespace.myClass.StringToObject() in D:leshascreenersrcStringToObject.cs:line 12
         at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Typically, when trying to reference specific elements of a json string without deserializing into a strongly typed object, you do not want to fully deserialize the object since you only use a subset of the data. In these cases, use the JsonDocument.Parse API:

var json = "{"cookies": { "id": 1 } }";

var options = new JsonDocumentOptions { AllowTrailingCommas = true };

using var document = JsonDocument.Parse(json, options);
Console.WriteLine(document.RootElement.GetProperty("cookies"));

If you absolutely want to use dynamic, there is no way to retrieve part of the structure since the underlying type, JsonElement, does not contain a Runtime binder that allows you to walk the object. As a result, you have two options: you can either cast the dynamic to JsonElement, or you can directly deserialize to JsonElement. This allows you to use the GetProperty method.

var str = "{"cookies": { "id": 1 } }";
var JsonObjectFromString = JsonSerializer.Deserialize<JsonElement>(str);
Console.WriteLine(JsonObjectFromString);
Console.WriteLine(((JsonElement)JsonObjectFromString).GetProperty("cookies"));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...