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

第三方JSON动态反序列化:如何根据对象类型匹配对应模型类?

问题解决方案

核心问题分析

你当前的JsonConverter直接标注在Properties字段上,导致只能访问到properties节点的JSON内容,无法获取外层的objectType字段值,因此无法判断应该将其反序列化为哪个目标模型(ContactPropertiesModel/DealPropertiesModel/PetPropertiesModel)。

解决方案步骤

1. 调整主模型的Converter位置

将JsonConverter从Properties字段移到WorkflowWebhookModel类上,这样就能在Converter中读取整个JSON对象,先获取objectType再处理properties。

修正后的主模型代码:

[DataContract]
[JsonConverter(typeof(WorkflowWebhookModelConverter))] // 类级别的Converter
public class WorkflowWebhookModel
{
    [DataMember(Name = "objectType")]
    public string ObjectType { get; set; }
    
    [DataMember(Name = "objectTypeId")]
    public string ObjectTypeId { get; set; }
    
    [DataMember(Name = "objectId")] // 修正原代码中字段名的笔误(原incobjectIdeption_date)
    public long? ObjectId { get; set; }
    
    [DataMember(Name = "properties")]
    public dynamic Properties { get; set; } // 移除字段上的Converter
}

2. 实现类级别的自定义Converter

编写WorkflowWebhookModelConverter,先读取基础字段拿到objectType,再根据类型反序列化对应的Properties模型:

public class WorkflowWebhookModelConverter : JsonConverter<WorkflowWebhookModel>
{
    public override WorkflowWebhookModel ReadJson(JsonReader reader, Type objectType, WorkflowWebhookModel existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;

        var jObject = JObject.Load(reader);
        var model = new WorkflowWebhookModel();

        // 反序列化基础字段
        model.ObjectType = jObject["objectType"]?.ToString();
        model.ObjectTypeId = jObject["objectTypeId"]?.ToString();
        model.ObjectId = jObject["objectId"]?.Value<long?>();

        // 根据objectType匹配对应的Properties模型
        var propertiesToken = jObject["properties"];
        if (propertiesToken != null && propertiesToken.Type == JTokenType.Object)
        {
            switch (model.ObjectType?.Trim().ToLower())
            {
                case "contact":
                    model.Properties = propertiesToken.ToObject<ContactPropertiesModel>(serializer);
                    break;
                case "deal":
                    model.Properties = propertiesToken.ToObject<DealPropertiesModel>(serializer);
                    break;
                case "pet":
                    model.Properties = propertiesToken.ToObject<PetPropertiesModel>(serializer);
                    break;
                default:
                    // 处理未知类型:可选返回原始JObject或抛出异常
                    model.Properties = propertiesToken.ToObject<JObject>(serializer);
                    break;
            }
        }

        return model;
    }

    public override void WriteJson(JsonWriter writer, WorkflowWebhookModel value, JsonSerializer serializer)
    {
        // 序列化逻辑(如果需要):根据Properties的实际类型生成对应JSON
        var jObject = new JObject();
        jObject.Add("objectType", value.ObjectType);
        jObject.Add("objectTypeId", value.ObjectTypeId);
        jObject.Add("objectId", value.ObjectId);

        if (value.Properties != null)
        {
            var propertiesToken = JToken.FromObject(value.Properties, serializer);
            jObject.Add("properties", propertiesToken);
        }

        jObject.WriteTo(writer);
    }
}

3. 确保目标模型字段映射正确

三个目标模型类需确保字段与JSON结构匹配,通过DataMember特性绑定JSON键名:

[DataContract]
public class PetPropertiesModel
{
    [DataMember(Name = "petName")]
    public string PetName { get; set; }
    
    [DataMember(Name = "petAge")]
    public int? PetAge { get; set; }
    // 其他专属属性
}

[DataContract]
public class ContactPropertiesModel
{
    [DataMember(Name = "contactName")]
    public string ContactName { get; set; }
    
    [DataMember(Name = "contactEmail")]
    public string ContactEmail { get; set; }
    // 其他专属属性
}

[DataContract]
public class DealPropertiesModel
{
    [DataMember(Name = "dealAmount")]
    public decimal? DealAmount { get; set; }
    
    [DataMember(Name = "dealStage")]
    public string DealStage { get; set; }
    // 其他专属属性
}

额外说明

  • 原代码中token.ToObject<PetPropertiesModel>()返回null,大概率是因为JSON结构与PetPropertiesModel字段不匹配,需检查字段名映射或JSON格式是否正确。
  • 若需处理更多类型,只需在switch分支中添加对应类型的判断即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:17:51