如何在Microsoft Graph Beta SDK中提取AuditData内SensitivityLabelEventData字段?
解决Microsoft Graph Beta SDK中UntypedObject嵌套字段提取问题
问题背景
在.NET项目中使用Microsoft Graph Beta SDK时,尝试从AuditLogRecord的AuditData属性内的SensitivityLabelEventData提取特定字段,但该数据以Microsoft.Kiota.Abstractions.Serialization.UntypedObject形式存储,无法直接访问属性。
原代码示例
var autditLogRecords = gsc.Security.AuditLog.Queries[auditLog_Search_id].Records.GetAsync().GetAwaiter().GetResult(); foreach (var auditLogRecord in autditLogRecords.Value) { var additionalData = auditLogRecord.AuditData.AdditionalData; var untypedObject = additionalData["SensitivityLabelEventData"] as Microsoft.Kiota.Abstractions.Serialization.UntypedObject; if (untypedObject != null) { // Attempt to access properties within UntypedObject var labelEventType = untypedObject.ToString(); // Intended to get the 'labelEventType' var sensitivityLabelId = untypedObject.ToString(); // Intended to get the 'SensitivityLabelId' var sensitivityLabelOwnerEmail = untypedObject.ToString(); // Intended to get the 'SensitivityLabelOwnerEmail' // Setting parameters for SQL command comm.Parameters.Add("@SensitivityLabelEventData_LabelEventType", SqlDbType.Int).Value = !string.IsNullOrEmpty(labelEventType) ? Convert.ToInt32(labelEventType) : DBNull.Value; comm.Parameters.Add("@SensitivityLabelEventData_SensitivityLabelId", SqlDbType.VarChar, 36).Value = !string.IsNullOrEmpty(sensitivityLabelId) ? sensitivityLabelId : (object)DBNull.Value; comm.Parameters.Add("@SensitivityLabelEventData_SensitivityLabelOwnerEmail", SqlDbType.NVarChar, 255).Value = !string.IsNullOrEmpty(sensitivityLabelOwnerEmail) ? sensitivityLabelOwnerEmail : (object)DBNull.Value; } }
遇到的问题
- 属性访问方式错误:直接将
UntypedObject转为字符串无法获取内部嵌套字段 - 属性转换失败:尝试转为
UntypedString或UntypedInteger无法提取实际值
解决方案
方法1:利用UntypedObject的Value属性转为字典访问
UntypedObject的Value属性存储了实际的嵌套数据(通常为Dictionary<string, object>类型),可以通过字典键名直接提取字段:
var autditLogRecords = gsc.Security.AuditLog.Queries[auditLog_Search_id].Records.GetAsync().GetAwaiter().GetResult(); foreach (var auditLogRecord in autditLogRecords.Value) { var additionalData = auditLogRecord.AuditData.AdditionalData; // 安全获取并转换UntypedObject if (additionalData.TryGetValue("SensitivityLabelEventData", out var eventDataObj) && eventDataObj is Microsoft.Kiota.Abstractions.Serialization.UntypedObject untypedObject) { // 将Value转为字典 if (untypedObject.Value is Dictionary<string, object> eventDataDict) { // 提取字段并做类型安全判断 var labelEventType = eventDataDict.TryGetValue("labelEventType", out var leValue) ? leValue as int? : null; var sensitivityLabelId = eventDataDict.TryGetValue("SensitivityLabelId", out var slIdValue) ? slIdValue as string : null; var sensitivityLabelOwnerEmail = eventDataDict.TryGetValue("SensitivityLabelOwnerEmail", out var slEmailValue) ? slEmailValue as string : null; // 绑定SQL参数 comm.Parameters.Add("@SensitivityLabelEventData_LabelEventType", SqlDbType.Int).Value = labelEventType ?? DBNull.Value; comm.Parameters.Add("@SensitivityLabelEventData_SensitivityLabelId", SqlDbType.VarChar, 36).Value = sensitivityLabelId ?? (object)DBNull.Value; comm.Parameters.Add("@SensitivityLabelEventData_SensitivityLabelOwnerEmail", SqlDbType.NVarChar, 255).Value = sensitivityLabelOwnerEmail ?? (object)DBNull.Value; } } }
方法2:反序列化为强类型对象(推荐用于频繁访问场景)
定义与SensitivityLabelEventData结构匹配的强类型类,通过Kiota序列化器将UntypedObject反序列化为该类,提升代码可读性和可维护性:
第一步:定义强类型类
public class SensitivityLabelEventData { public int? LabelEventType { get; set; } public string SensitivityLabelId { get; set; } public string SensitivityLabelOwnerEmail { get; set; } }
第二步:修改代码实现反序列化
var autditLogRecords = gsc.Security.AuditLog.Queries[auditLog_Search_id].Records.GetAsync().GetAwaiter().GetResult(); // 获取Graph客户端自带的序列化器 var serializer = gsc.RequestAdapter.SerializerFactory.GetSerializer("application/json"); foreach (var auditLogRecord in autditLogRecords.Value) { var additionalData = auditLogRecord.AuditData.AdditionalData; if (additionalData.TryGetValue("SensitivityLabelEventData", out var eventDataObj) && eventDataObj is Microsoft.Kiota.Abstractions.Serialization.UntypedObject untypedObject) { // 反序列化为强类型对象 var eventData = serializer.Deserialize<SensitivityLabelEventData>(untypedObject.Value); // 绑定SQL参数 comm.Parameters.Add("@SensitivityLabelEventData_LabelEventType", SqlDbType.Int).Value = eventData.LabelEventType ?? DBNull.Value; comm.Parameters.Add("@SensitivityLabelEventData_SensitivityLabelId", SqlDbType.VarChar, 36).Value = eventData.SensitivityLabelId ?? (object)DBNull.Value; comm.Parameters.Add("@SensitivityLabelEventData_SensitivityLabelOwnerEmail", SqlDbType.NVarChar, 255).Value = eventData.SensitivityLabelOwnerEmail ?? (object)DBNull.Value; } }
注意事项
- 始终使用
TryGetValue访问字典,避免键不存在引发异常 - 强类型类的属性名需与Graph返回的字段名完全匹配(注意大小写)
- 对于不确定的字段类型,使用可空类型(如
int?)避免转换失败
内容的提问来源于stack exchange,提问作者John Park
相关产品推荐
相关产品推荐

