如何在C#中解析Exchange Online组返回的三种嵌套JSON?
解决Exchange Online组成员JSON的多态反序列化问题
问题场景
在基于PowerShell的Azure Function App中管理Exchange Online邮箱时,通过Get-DistributionGroupMember获取的组成员会生成三种不同格式的GroupMembers JSON字段:
- 无成员时为
null - 单个成员时为序列化后的单对象字符串(如
"{\"Identity\":\"smtp:nivek@domain.com\"}") - 多个成员时为序列化后的对象数组字符串(如
["{\"Identity\":\"smtp:nivek2@domain.com\"}","{\"Identity\":\"smtp:nivek@domain.com\"}"])
需要在C#中完成这三种情况的正确反序列化,统一处理成员数据。
优化后的实现
调整类定义
不需要单独定义数组类,直接复用单个用户身份类即可,简化结构:
// 单个用户身份信息 class ExchPS_UserIdentity_Data { [JsonProperty(nameof(Identity))] public string Identity { get; set; } = string.Empty; } // 顶层回复结构 class ExchPS_GetUserMailData_Reply { [JsonProperty(nameof(GroupMembers))] public string GroupMembers { get; set; } = string.Empty; [JsonProperty(nameof(ForwardingAddressID))] public string ForwardingAddressID { get; set; } = string.Empty; }
统一反序列化逻辑
用List<ExchPS_UserIdentity_Data>统一存储成员,兼容0个、1个、多个成员的场景:
// 反序列化顶层回复 ExchPS_GetUserMailData_Reply getUserMailDataReplyDeserialized = JsonConvert.DeserializeObject<ExchPS_GetUserMailData_Reply>(AzureResponseDeserialized.OutputData); List<ExchPS_UserIdentity_Data> groupMembers = new List<ExchPS_UserIdentity_Data>(); // 处理GroupMembers字段 if (!string.IsNullOrWhiteSpace(getUserMailDataReplyDeserialized.GroupMembers)) { string rawData = getUserMailDataReplyDeserialized.GroupMembers.Trim(); // 判断是数组还是单个对象 if (rawData.StartsWith("[")) { // 数组格式:反序列化为数组后添加到列表 var membersArray = JsonConvert.DeserializeObject<ExchPS_UserIdentity_Data[]>(rawData); if (membersArray != null) { groupMembers.AddRange(membersArray); } } else if (rawData.StartsWith("{")) { // 单个对象格式:反序列化为实例后加入列表 var singleMember = JsonConvert.DeserializeObject<ExchPS_UserIdentity_Data>(rawData); if (singleMember != null) { groupMembers.Add(singleMember); } } } // 后续业务逻辑:统一判断是否有成员 if (groupMembers.Any()) { ForwardMbx = true; // 示例:取第一个成员的Identity,可按需遍历所有成员 ForwardMbxTo = groupMembers.First().Identity; } else { ForwardMbx = false; ForwardMbxTo = string.Empty; }
关键注意点
- 对原始字符串做
Trim()处理,避免首尾空格导致首字符判断错误 - 用列表统一存储成员,无需区分单个/多个的业务逻辑,简化后续代码
- 空值场景直接跳过处理,最终列表为空,通过
Any()判断即可
内容的提问来源于stack exchange,提问作者scooter133
相关产品推荐
相关产品推荐

