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
678 views
in Technique[技术] by (71.8m points)

c# - Read value from dynamic property from json payload

I have a simple model that I used as a request payload

public class CommandRequest
{
    public CommandType Type { get; set; }
    public dynamic Attributes { get; set; }
}

In controller action I need to read some property from dynamic Attributes

public async Task<IActionResult> Commands([FromBody] CommandRequest requestBody)
{
    string name = requestBody.Attributes.Name;
    ...
}

Got the following exception:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.Text.Json.JsonElement' does not contain a definition for 'Name'

How can I read that property?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

Simply declaring something as dynamic doesn't guarantee that the resulting concrete object implements IDynamicMetaObjectProvider and allows for runtime definition of properties. Rather, dynamic simply means an object to which all compile-time checking has been turned off, and so all method and member references to it will be resolved in runtime. See:

Now, when you deserialize a JSON object to a member declared as dynamic with Json.NET, Newtonsoft will chose JObject as the concrete type to which to deserialize. As its base type JToken implements IDynamicMetaObjectProvider you can do things like requestBody.Attributes.Name and the .Net runtime will forward the property resolution to the JObject which will look the property up inside its list of properties. However, this doesn't happen automatically, Newtonsoft had to enhance JToken to make dynamic property access possible.

System.Text.Json, however, does not have built-in support for deserializing free-form JSON to some custom type implementing IDynamicMetaObjectProvider, so you will need to use the compile-time methods of the actual type returned, viz. JsonElement, to access the JSON data contained therein:

var name = requestBody.Attributes.GetProperty("Name").ToString();

Or, you could cast it for clarity:

var name = ((JsonElement)requestBody.Attributes).GetProperty("Name").ToString();

Demo fiddle here.


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

...