WebAPI场景下C#实现类似JS动态添加属性的addKvp方法问题
方案1:使用ExpandoObject(完全匹配JS动态对象用法)
ExpandoObject是C#内置的动态类型,底层基于字典实现,支持运行时动态增删属性,所有主流JSON序列化库(System.Text.Json、Newtonsoft.Json)都原生支持将其序列化为标准JSON对象,不会生成嵌套字典结构,前端可直接解析。
AddKvp实现
using System.Dynamic; public static void AddKvp(object element, string key, object value) { if (element is not IDictionary<string, object> dict) { throw new ArgumentException("element参数需为ExpandoObject类型", nameof(element)); } dict[key] = value; }
使用示例(和JS示例逻辑完全一致)
dynamic abc = new ExpandoObject(); AddKvp(abc, "foo", "bar"); Console.WriteLine(abc.foo); // 输出:bar
序列化后的JSON结果:
{"foo":"bar"}
方案2:带扩展字段的强类型模型(适合有固定属性的场景)
如果CMS对象存在部分固定已知的属性,剩余为动态字段,可以用[JsonExtensionData]特性实现,序列化时动态属性会自动展开到JSON根层级,不需要额外处理。
模型定义
// 用System.Text.Json的话特性命名空间是System.Text.Json.Serialization using Newtonsoft.Json; public class CmsXmlElement { // 固定已知属性 public string NodeId { get; set; } public string NodeName { get; set; } // 所有动态属性存储在该字段,序列化时自动展开为根级属性 [JsonExtensionData] public IDictionary<string, object> ExtraFields { get; set; } = new Dictionary<string, object>(); }
对应AddKvp实现
public static void AddKvp(CmsXmlElement element, string key, object value) { element.ExtraFields[key] = value; }
使用示例
var element = new CmsXmlElement { NodeId = "1001", NodeName = "banner" }; AddKvp(element, "imgUrl", "https://xxx.com/1.png"); AddKvp(element, "link", "/activity");
序列化后的JSON结果:
{"NodeId":"1001","NodeName":"banner","imgUrl":"https://xxx.com/1.png","link":"/activity"}
补充说明
C#是强类型语言,普通强类型对象的结构在编译时就已确定,无法在运行时新增成员,因此不要使用普通object作为动态属性的承载类型,统一使用上述两种方案即可完全实现你要的JS同等效果,无需额外搭建Node服务中间层。
内容的提问来源于stack exchange,提问作者Count Spatula
相关产品推荐
相关产品推荐

