使用C# SharePoint CSOM获取字段值显示名称及文件元数据展示问题
嘿,看起来你已经搞定了用CSOM获取文件元数据的基础逻辑,现在想要把字段的显示名称(而不是代码里的内部名称)展示出来,同时还要让字段值显示得更友好对吧?我来给你调整下代码,顺便解决字段值的友好显示问题~
调整后的完整代码
using Microsoft.SharePoint.Client; using System; using System.Collections.Generic; using System.Linq; public static void PrintFileMeta(string path) { using (var context = GetContext()) // 假设你的GetContext()方法已经正确返回ClientContext { File file = context.Web.GetFileByServerRelativeUrl(path); var item = file.ListItemAllFields; // 加载列表项,同时加载父列表的字段集合(包含内部名称和显示名称) context.Load(item); context.Load(item.ParentList, l => l.Fields.Include(f => f.InternalName, f => f.Title)); context.ExecuteQuery(); // 先收集所有需要处理的字段、值,以及要加载的用户ID(优化性能) Dictionary<string, Field> fieldMap = new Dictionary<string, Field>(); Dictionary<string, object> valueMap = new Dictionary<string, object>(); List<int> userIdsToLoad = new List<int>(); foreach (string internalFieldName in item.FieldValues.Keys) { var field = item.ParentList.Fields.GetByInternalNameOrTitle(internalFieldName); fieldMap.Add(internalFieldName, field); object fieldValue = item.FieldValues[internalFieldName]; valueMap.Add(internalFieldName, fieldValue); // 收集用户字段的LookupId,后续批量加载 if (field is FieldUser && fieldValue is FieldUserValue userValue) { if (userValue.LookupId > 0) { userIdsToLoad.Add(userValue.LookupId); } } } // 批量加载用户信息,避免多次ExecuteQuery Dictionary<int, string> userDisplayNameMap = new Dictionary<int, string>(); if (userIdsToLoad.Any()) { var users = context.Web.GetUsersByIds(userIdsToLoad); context.Load(users, u => u.Include(u => u.Id, u => u.Title)); context.ExecuteQuery(); foreach (var user in users) { userDisplayNameMap.Add(user.Id, user.Title); } } // 输出格式化后的元数据 foreach (var kvp in valueMap) { string internalName = kvp.Key; object rawValue = kvp.Value; Field field = fieldMap[internalName]; string fieldDisplayName = field.Title ?? internalName; string valueDisplayName = GetFriendlyFieldValue(rawValue, field, userDisplayNameMap); Console.WriteLine($"【{fieldDisplayName}】: {valueDisplayName}"); } } } /// <summary> /// 根据字段类型返回友好的显示值 /// </summary> private static string GetFriendlyFieldValue(object rawValue, Field field, Dictionary<int, string> userDisplayNameMap) { if (rawValue == null) { return "空"; } // 处理用户/用户组字段 if (field is FieldUser) { var userValue = rawValue as FieldUserValue; if (userValue != null && userDisplayNameMap.ContainsKey(userValue.LookupId)) { return userDisplayNameMap[userValue.LookupId]; } return userValue?.LookupValue ?? string.Empty; } // 处理查找字段 else if (field is FieldLookup) { var lookupValue = rawValue as FieldLookupValue; return lookupValue?.LookupValue ?? string.Empty; } // 处理日期时间字段 else if (field is FieldDateTime) { if (rawValue is DateTime dateValue) { return dateValue.ToString("yyyy-MM-dd HH:mm:ss"); } } // 处理布尔字段 else if (field is FieldBoolean) { return (bool)rawValue ? "是" : "否"; } // 处理多选项字段(比如复选框) else if (field is FieldMultiChoice) { var multiValue = rawValue as string[]; return multiValue != null ? string.Join("、", multiValue) : string.Empty; } // 其他类型直接转字符串 return rawValue.ToString(); }
关键说明
- 获取字段显示名称:原代码只加载了列表项的字段值,但字段的显示名称存在父列表的
Fields集合中。所以我们需要加载item.ParentList.Fields并指定包含InternalName和Title,这样就能通过字段的内部名称映射到对应的显示名称。 - 字段值友好格式化:不同类型的字段直接
ToString()会得到不友好的结果(比如用户字段会显示Microsoft.SharePoint.Client.FieldUserValue),所以针对每种字段类型做了特殊处理,确保输出易读的内容。 - 性能优化:如果文件元数据中有多个用户类型的字段,我们先收集所有需要加载的用户ID,一次性调用
ExecuteQuery加载用户信息,避免多次请求SharePoint导致性能下降。
额外提示
如果你的文档库有自定义字段,这段代码也能自动适配,只要字段类型在上述处理逻辑中覆盖到了。如果有特殊类型的字段(比如附件、超链接),可以在GetFriendlyFieldValue函数里继续添加对应的处理分支。
内容的提问来源于stack exchange,提问作者hjalpmig
相关产品推荐
相关产品推荐

