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

C#中动态JSON序列化反序列化:按需构造请求Payload

解决C#中动态JSON请求Payload的Data结构问题

我需要通过C#提交JSON请求,请求Payload中的data部分需根据业务规则动态变更。已知所有可能的data结构,但请求中仅需使用符合规则的对应结构。

请求示例

示例1

{"activity": {"referenceId": "","data": {"rents": 0.0,"wages": 0.0}}}

示例2

{"activity": {"referenceId": "","data": {"transport": 0.0,"salaries": 0.0}}}

示例3

{"activity": {"referenceId": "","data": {"water": 0.0,"miscellaneous": 0.0}}}

现有POCO代码

我已经按常规方式定义了POCO类,但不知道怎么满足动态结构的需求。原本想创建一个“主”Data对象,只传递需要的属性,但在这里卡住了。现有代码如下:

public class Rootobject
{
    public Activity activity { get; set; }
}

public class Activity
{
    public string referenceId { get; set; }
    public Data data { get; set; }
}

public class Data // 继承这个主类行不通
{
    public float water { get; set; }
    public float miscellaneous { get; set; }
    public float transport { get; set; }
    public float salaries { get; set; }
    public float rents { get; set; }
    public float wages { get; set; }
}

可行解决方案

方案1:使用继承+JsonSubTypes(强类型场景推荐)

为每种data结构定义独立子类,借助JsonSubTypes库(或System.Text.Json的多态序列化特性)控制序列化逻辑:

using JsonSubTypes;
using Newtonsoft.Json;

public class Rootobject
{
    public Activity activity { get; set; }
}

public class Activity
{
    public string referenceId { get; set; }
    [JsonConverter(typeof(JsonSubtypes))]
    [JsonSubtypes.KnownSubType(typeof(RentWagesData), "rentWages")]
    [JsonSubtypes.KnownSubType(typeof(TransportSalariesData), "transportSalaries")]
    [JsonSubtypes.KnownSubType(typeof(WaterMiscData), "waterMisc")]
    public BaseData data { get; set; }
}

public abstract class BaseData { }

public class RentWagesData : BaseData
{
    public float rents { get; set; }
    public float wages { get; set; }
}

public class TransportSalariesData : BaseData
{
    public float transport { get; set; }
    public float salaries { get; set; }
}

public class WaterMiscData : BaseData
{
    public float water { get; set; }
    public float miscellaneous { get; set; }
}

序列化时传入对应子类实例,即可生成仅包含目标属性的JSON。

方案2:使用匿名类型(快速实现)

无需定义复杂类结构,直接根据业务规则创建匿名类型:

// 业务规则要求传入rents和wages的场景
var payload = new
{
    activity = new
    {
        referenceId = "",
        data = new
        {
            rents = 0.0f,
            wages = 0.0f
        }
    }
};

// 序列化生成JSON
string json = JsonConvert.SerializeObject(payload);

这种方式简单直接,适合无需复用结构的临时场景。

方案3:使用Dictionary<string, float>(灵活场景)

将data定义为字典类型,动态添加需要的键值对:

public class Rootobject
{
    public Activity activity { get; set; }
}

public class Activity
{
    public string referenceId { get; set; }
    public Dictionary<string, float> data { get; set; }
}

// 使用示例
var activity = new Activity
{
    referenceId = "",
    data = new Dictionary<string, float>
    {
        {"rents", 0.0f},
        {"wages", 0.0f}
    }
};

string json = JsonConvert.SerializeObject(new Rootobject { activity = activity });

该方式灵活性最高,适合属性组合多变的场景。

方案4:使用条件序列化(基于原有Data类改造)

若不想修改原有类结构,可结合JsonIgnore和空值忽略配置,只序列化需要的属性:

using Newtonsoft.Json;

public class Data
{
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public float? water { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public float? miscellaneous { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public float? transport { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public float? salaries { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public float? rents { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public float? wages { get; set; }
}

// 使用示例
var data = new Data
{
    rents = 0.0f,
    wages = 0.0f
};

string json = JsonConvert.SerializeObject(
    new Rootobject { activity = new Activity { referenceId = "", data = data } },
    new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:50:27