You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:10:40