You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用NewtonSoft时,如何解决动态对象的ValueKind = Object问题?

解决Dynamic类型Model的ValueKind = Object转换问题

请求负载会存入声明为Dynamic类型的parts.Model中,这是一个多端点共用的服务,需要保留结构同时解决ValueKind = Object的处理问题。

示例Model结构

"Model": {
    "CustomerSurname": "Johnson",
    "Title": "Mr",
    "PlanType": "Help Extension",
    "ServiceAdvisor": "Jeff Matle",
    "DealershipName": "Goldwagen Pretoria"
}

尝试过的无效代码

之前多次用JsonSerializer.Deserialize都没效果,代码如下:

public async Task<IActionResult> SendSms([FromBody] CreatePart parts)
{
    parts.DateMessageScheduled = DateTime.Now;
    parts.DateCutOff = DateTime.MaxValue;
    parts.CommunicationTypeId = CommunicationType.Codes.SMS;

    dynamic obj = parts.Model;

    JsonElement jsonString = obj;

    var dynamicObject = JsonSerializer.Deserialize<JsonElement>(jsonString);

    var result = await _createNewPartService.Post(parts);

    return new JsonResult(result);
}

执行后dynamicObject的结果:

ValueKind = Object : "{
        "CustomerSurname": "Johnson",
        "Title": "Mr",
        "PlanType": "Help Extension",
        "ServiceAdvisor": "Jeff Matle",
        "DealershipName": "Goldwagen Pretoria"
    }"

解决方案

问题核心:ASP.NET Core会把动态JSON自动反序列化为JsonElement类型,所以parts.Model本质就是JsonElement,不需要重复反序列化,直接处理这个对象即可。

方法1:转成动态ExpandoObject(保留完整结构)

写一个扩展方法把JsonElement转成可直接访问属性的动态对象:

using System.Dynamic;
using System.Text.Json;

public static class JsonElementExtensions
{
    public static ExpandoObject ToExpandoObject(this JsonElement element)
    {
        var expando = new ExpandoObject();
        var dictionary = (IDictionary<string, object>)expando;

        foreach (var property in element.EnumerateObject())
        {
            switch (property.Value.ValueKind)
            {
                case JsonValueKind.Object:
                    dictionary[property.Name] = property.Value.ToExpandoObject();
                    break;
                case JsonValueKind.Array:
                    var arrayList = new List<object>();
                    foreach (var item in property.Value.EnumerateArray())
                    {
                        arrayList.Add(item.ValueKind == JsonValueKind.Object ? item.ToExpandoObject() : item.GetValue());
                    }
                    dictionary[property.Name] = arrayList;
                    break;
                default:
                    dictionary[property.Name] = property.Value.GetValue();
                    break;
            }
        }
        return expando;
    }

    private static object GetValue(this JsonElement element)
    {
        return element.ValueKind switch
        {
            JsonValueKind.String => element.GetString(),
            JsonValueKind.Number => element.TryGetInt64(out long l) ? l : element.GetDouble(),
            JsonValueKind.True => true,
            JsonValueKind.False => false,
            JsonValueKind.Null => null,
            _ => element.ToString()
        };
    }
}

然后在接口方法里使用:

public async Task<IActionResult> SendSms([FromBody] CreatePart parts)
{
    parts.DateMessageScheduled = DateTime.Now;
    parts.DateCutOff = DateTime.MaxValue;
    parts.CommunicationTypeId = CommunicationType.Codes.SMS;

    // 直接转换为动态对象
    dynamic dynamicModel = ((JsonElement)parts.Model).ToExpandoObject();

    // 可以直接访问属性,比如获取姓氏
    var customerSurname = dynamicModel.CustomerSurname;

    var result = await _createNewPartService.Post(parts);

    return new JsonResult(result);
}

方法2:直接读取JsonElement属性(仅需读取特定值时用)

如果不需要完整的动态对象,只是读取个别属性,直接操作JsonElement更简单:

public async Task<IActionResult> SendSms([FromBody] CreatePart parts)
{
    parts.DateMessageScheduled = DateTime.Now;
    parts.DateCutOff = DateTime.MaxValue;
    parts.CommunicationTypeId = CommunicationType.Codes.SMS;

    JsonElement modelElement = (JsonElement)parts.Model;
    // 读取指定属性值
    string customerSurname = modelElement.GetProperty("CustomerSurname").GetString();
    string title = modelElement.GetProperty("Title").GetString();

    var result = await _createNewPartService.Post(parts);

    return new JsonResult(result);
}

内容的提问来源于stack exchange,提问作者Zhilong Liang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:57:10