从 json 负载中的动态 属性 中读取值

Read value from dynamic property from json payload

我有一个用作请求负载的简单模型

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

在控制器操作中,我需要从动态 Attributes

中读取一些 属性
public async Task<IActionResult> Commands([FromBody] CommandRequest requestBody)
{
    string name = requestBody.Attributes.Name;
    ...
}

出现以下异常:

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

我如何阅读 属性?

  1. 您可以在 JsonElement 上使用 GetProperty 方法来获取您想要的 属性。
  2. 可以用JsonConvert.Deseralize("jsonpayload")反序列化到Attributes的model中,直接用"."获取Name。表示法。
  3. 您可以反序列化为 Dictionary 并将 属性 名称作为 Dict["Name"].

简单地将某些内容声明为 dynamic 并不能保证生成的具体对象实现 IDynamicMetaObjectProvider 并允许运行时定义属性。相反,dynamic 只是表示一个 object,所有 compile-time 检查都已关闭,因此对它的所有方法和成员引用都将在运行时解析。参见:

现在,当您将 JSON 对象反序列化为使用 Json.NET 声明为 dynamic 的成员时,Newtonsoft 将选择 JObject as the concrete type to which to deserialize. As its base type JToken 实现 IDynamicMetaObjectProvider,您可以执行 requestBody.Attributes.Name 之类的操作,.Net 运行时会将 属性 分辨率转发给 JObject,后者将在其属性列表中查找 属性。但是,这不会自动发生,Newtonsoft 必须增强 JToken 才能实现动态 属性 访问。

System.Text.Json,但是,built-in 不支持将 free-form JSON 反序列化为某些实现 IDynamicMetaObjectProvider 的自定义类型,因此您需要使用返回的实际类型的 compile-time 方法,即。 JsonElement,访问其中包含的 JSON 数据:

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

或者,为了清楚起见,您可以强制转换它:

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

演示 fiddle here.