当lookupid不在用户信息列表中时,如何使用MS Graph获取SharePoint用户信息

后端开发 2026-07-09

我正在连接到一个站点并存储它的ID

var site = System.Threading.Tasks.Task.Run(() => graphClient.Sites[siteId].GetAsync(requestConfiguration => requestConfiguration.QueryParameters.Expand = new string[] { "drives" })).Result;

siteActualId = site.Id;

然后我遍历驱动器以找到我感兴趣的站点。

接着我处理每个项,对于是文件夹的情况,我处理它的子项。

当我得到一个条目是文档时,我获取它的列表项

doc = System.Threading.Tasks.Task.Run(() => graphClient.Drives[driveId].Items[item.Id].GetAsync(requestConfiguration => requestConfiguration.QueryParameters.Expand = new string[] { "ListItem" })).Result;

然后我使用字段的附加数据来获取字段值

var fields = doc.ListItem.Fields.AdditionalData;

values[APPROVAL_COMMENTS] = GetFieldValue(fields, "ApprovalComments");

        private string GetFieldValue(IDictionary<string, object> fields, string key, bool date = false)
        {
            if (fields.ContainsKey(key))
            {
                if (date)
                    return ((DateTime)fields[key]).AddHours(offset).ToString("yyyy/MM/dd HH:mm:ss");
                return fields[key].ToString();
            }
            return string.Empty;
        }

这一切都能正常工作。不过当存在一个用户字段时,我得到的不是姓名,而是一个ID;我再用这个ID去用户信息列表中查找该用户的姓名

values[APPROVER] = GetUserFieldValue(fields, "DocumentApproverLookupId");

        private string GetUserFieldValue(IDictionary<string, object> fields, string lookupId)
        {
            if (!fields.ContainsKey(lookupId))
                return string.Empty;

            string id = (string)fields[lookupId];

            if (id.Length == 0)
                return string.Empty;

            if (!UserNames.ContainsKey(id))
            {
                if (token == null || token?.ExpiresOn < DateTime.UtcNow)
                    token = clientSecretCredential.GetToken(new TokenRequestContext(scopes));

                var client = new RestClient($"https://graph.microsoft.com/v1.0/sites/{siteActualId}/lists('User Information List')/items/{id}?$expand=fields($select=Title)");
                var request = new RestRequest(Method.GET);

                request.AddHeader("Authorization", "Bearer " + token?.Token);

                var response = client.Execute(request);

                if (!string.IsNullOrEmpty(response.ErrorMessage))
                    throw new Exception("User name lookup failed: " + response.ErrorMessage);

                int i = response.Content.LastIndexOf(",\"Title\":\"");

                if (i == -1)
                    UserNames.Add(id, "Unknown");
                else
                {
                    i += 10;
                    int j = response.Content.IndexOf("\"", i);

                    UserNames.Add(id, response.Content.Substring(i, j - i));
                }
            }

            return UserNames[id];
        }

这在大多数情况下能工作,但也有一些ID不在列表中。

如果ID不在站点的用户信息列表中,我该如何获取该用户的姓名?

解决方案

如果你在用户查找字段中有用户的ID,该ID绝对必须在该站点的用户信息列表中。请确保你查看的是正确站点的信息列表(与条目来自的站点相同)。请注意,这些ID是按站点区分的。也就是说,同一个用户在站点A上的ID可能是1,在站点B上的ID可能是42。

另一种导致找不到用户的原因是站点上的用户数量,默认是100(据我记得),因此你可能需要在查询用户信息列表时添加 $top=1000来获取更多用户。

备选方案

虽然不是直接的解决办法,但据我所知,这个方法可以帮我绕过这个问题。

当你获取列表项时,可以指定你想要返回的字段,并且你可以请求不带LookupId扩展的字段

var li = System.Threading.Tasks.Task.Run(() =\> graphClient.Drives\[driveId\].Items\[item.Id\].ListItem.GetAsync(requestConfiguration =\> requestConfiguration.QueryParameters.Expand = new string\[\] { "fields($select=DocumentApprover,DocumentApproverLookupId)" })).Result;

这将返回该字段中的姓名。

有点烦人的是显示名不会自动返回,所以如果你不知道字段名,首先需要获取所有字段,然后对返回的任何LookupId字段再调用一次,但至少它似乎在起作用。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章