.NET中如何用Json.NET序列化name/value数组形式的attributes属性?
问题
在.NET中是否有办法将attributes属性序列化为name/value形式?我无法找到合适的方式将类序列化为包含sport、venue、city、province等字段的attributes属性,期望生成的JSON结构如下:
{"uid": "uuid","object": "live_event","title": "Event Name","event_start": "2022-10-10T12:00:00:000Z","timezone": "America/Denver","external_id": "some_external_user_generated_id","container_uid": "02f8270a-8662-45b3-898a-c915a68cdf87","description": "Description of the event","short_description": "Short description of the event","attributes": [{ "sport": "Soccer" },{ "venue": "New Park" },{ "city": "Calgary" },{ "province": "Alberta" },{ "teams": ["teamA", "teamB"] }]}
现有CreateEventRequest类定义如下:
public class CreateEventRequest : VidFlexRequest, ISaveEventRequest { [JsonProperty("uid", NullValueHandling = NullValueHandling.Ignore)] public string UId { get; set; } [JsonProperty("title")] public string Title { get; set; } [JsonProperty("event_start")] public string EventStart { get; set; } [JsonProperty("timezone")] public string TimeZone { get; set; } [JsonProperty("external_id")] public string ExternalId { get; set; } [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] public string Description { get; set; } [JsonProperty("short_description", NullValueHandling = NullValueHandling.Ignore)] public string ShortDescription { get; set; } }
解决方案
可以通过自定义属性类型+Json.NET序列化特性实现需求,具体步骤如下:
1. 定义单个属性项类型
attributes中的每个元素都是单键值对(值可以是字符串或数组),可以用带JsonExtensionData特性的类实现类型安全的动态键处理:
public class AttributeItem { [JsonExtensionData] public Dictionary<string, object> Data { get; set; } = new Dictionary<string, object>(); // 便捷构造函数,快速创建单键值对 public AttributeItem(string key, object value) { Data[key] = value; } }
2. 更新CreateEventRequest类
补充缺失的字段(object、container_uid),并添加attributes属性:
public class CreateEventRequest : VidFlexRequest, ISaveEventRequest { [JsonProperty("uid", NullValueHandling = NullValueHandling.Ignore)] public string UId { get; set; } [JsonProperty("title")] public string Title { get; set; } [JsonProperty("event_start")] public string EventStart { get; set; } [JsonProperty("timezone")] public string TimeZone { get; set; } [JsonProperty("external_id")] public string ExternalId { get; set; } [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] public string Description { get; set; } [JsonProperty("short_description", NullValueHandling = NullValueHandling.Ignore)] public string ShortDescription { get; set; } // 新增attributes属性 [JsonProperty("attributes")] public List<AttributeItem> Attributes { get; set; } = new List<AttributeItem>(); // 补充JSON中要求的固定字段 [JsonProperty("object")] public string ObjectType => "live_event"; [JsonProperty("container_uid", NullValueHandling = NullValueHandling.Ignore)] public string ContainerUid { get; set; } }
3. 构造实例并序列化
创建请求实例,填充属性后用Json.NET序列化:
var request = new CreateEventRequest { UId = "uuid", Title = "Event Name", EventStart = "2022-10-10T12:00:00:000Z", TimeZone = "America/Denver", ExternalId = "some_external_user_generated_id", ContainerUid = "02f8270a-8662-45b3-898a-c915a68cdf87", Description = "Description of the event", ShortDescription = "Short description of the event", Attributes = new List<AttributeItem> { new AttributeItem("sport", "Soccer"), new AttributeItem("venue", "New Park"), new AttributeItem("city", "Calgary"), new AttributeItem("province", "Alberta"), new AttributeItem("teams", new[] {"teamA", "teamB"}) } }; var json = JsonConvert.SerializeObject(request, Formatting.Indented);
4. 简洁替代方案
如果不需要类型安全,可直接将Attributes定义为List<Dictionary<string, object>>,省去自定义类步骤:
[JsonProperty("attributes")] public List<Dictionary<string, object>> Attributes { get; set; } = new List<Dictionary<string, object>>();
构造时直接添加字典:
Attributes = new List<Dictionary<string, object>> { new Dictionary<string, object> { {"sport", "Soccer"} }, new Dictionary<string, object> { {"venue", "New Park"} }, new Dictionary<string, object> { {"city", "Calgary"} }, new Dictionary<string, object> { {"province", "Alberta"} }, new Dictionary<string, object> { {"teams", new[] {"teamA", "teamB"}} } };
注意事项
- 确保项目已引用Newtonsoft.Json(Json.NET)包,否则
JsonProperty等特性无法使用 - 若使用System.Text.Json,需替换为
JsonPropertyName特性,序列化逻辑保持一致
内容的提问来源于stack exchange,提问作者Mike Flynn
相关产品推荐
相关产品推荐

