如何在C#中通过SharePoint列ID获取托管元数据术语集?
核心思路
Graph API确实未直接暴露托管元数据字段关联的术语集ID,但可以通过SharePoint客户端对象模型(CSOM)或PnP Core SDK获取字段的完整定义,从中提取术语集和术语组的ID,再调用术语库接口获取所有术语。
方法1:使用PnP Core SDK(推荐,现代开发首选)
PnP Core SDK封装了更简洁的API,无需手动解析SchemaXml,直接获取Taxonomy字段的关联信息。
实现步骤与代码
- 安装PnP Core SDK NuGet包:
Install-Package PnP.Core - 初始化PnP上下文并执行操作:
using PnP.Core.Services; using PnP.Core.Model.SharePoint; using PnP.Core.Model.Taxonomy; // 初始化PnP上下文(以应用权限为例,也支持用户凭据) var pnpContextFactory = new PnPContextFactory(); var settings = new PnPContextOptions { SiteUrl = new Uri("https://yourtenant.sharepoint.com/sites/yoursite"), ClientId = "your-app-client-id", ClientSecret = "your-app-client-secret" }; using (var context = await pnpContextFactory.CreateAsync(settings)) { // 获取目标列表 var targetList = await context.Web.Lists.GetByTitleAsync("你的列表名称", p => p.Fields); // 找到目标托管元数据字段(替换为你的字段内部名称) var taxonomyField = targetList.Fields.FirstOrDefault(f => f.InternalName == "你的字段内部名称") as ITaxonomyField; if (taxonomyField != null) { // 获取关联的术语集 var termSet = await context.Taxonomy.TermSets.GetByIdAsync(taxonomyField.TermSetId, p => p.Terms.Include(t => t.Labels, t => t.Children)); // 递归获取所有术语(包含子术语) var allTerms = GetAllTerms(termSet.Terms).ToList(); // 处理术语数据,比如输出术语标签 foreach (var term in allTerms) { Console.WriteLine(term.Labels.First(l => l.IsDefault).Value); } } } // 递归获取所有层级的术语 IEnumerable<ITerm> GetAllTerms(IEnumerable<ITerm> terms) { foreach (var term in terms) { yield return term; if (term.Children.Any()) { foreach (var childTerm in GetAllTerms(term.Children)) { yield return childTerm; } } } }
方法2:使用传统SharePoint CSOM
如果项目依赖传统CSOM,也可以通过解析字段的SchemaXml或转换为TaxonomyField来获取ID:
实现步骤与代码
- 安装CSOM NuGet包:
Install-Package Microsoft.SharePointOnline.CSOM和Install-Package Microsoft.SharePoint.Client.Taxonomy - 编写代码:
using Microsoft.SharePoint.Client; using Microsoft.SharePoint.Client.Taxonomy; // 初始化ClientContext var siteUrl = "https://yourtenant.sharepoint.com/sites/yoursite"; var clientContext = new ClientContext(siteUrl); // 配置凭据(应用权限或用户凭据) clientContext.AuthenticationMode = ClientAuthenticationMode.Default; clientContext.Credentials = new SharePointOnlineCredentials("username@tenant.onmicrosoft.com", ConvertToSecureString("password")); try { // 获取目标列表 var targetList = clientContext.Web.Lists.GetByTitle("你的列表名称"); clientContext.Load(targetList.Fields); await clientContext.ExecuteQueryAsync(); // 找到目标托管元数据字段 var field = targetList.Fields.FirstOrDefault(f => f.InternalName == "你的字段内部名称"); if (field != null && field.TypeAsString == "TaxonomyFieldType") { var taxonomyField = field as TaxonomyField; clientContext.Load(taxonomyField, tf => tf.TermSetId, tf => tf.TermGroupId); await clientContext.ExecuteQueryAsync(); // 获取术语库会话 var taxonomySession = TaxonomySession.GetTaxonomySession(clientContext); var termStore = taxonomySession.GetDefaultSiteCollectionTermStore(); var termSet = termStore.GetTermSet(taxonomyField.TermSetId); // 加载所有术语(包含子术语) var terms = termSet.GetAllTerms(); clientContext.Load(terms, t => t.Include( term => term.Labels, term => term.TermsCount)); await clientContext.ExecuteQueryAsync(); // 处理术语数据 foreach (var term in terms) { var defaultLabel = term.Labels.First(l => l.IsDefaultLabel); Console.WriteLine(defaultLabel.Value); } } } finally { clientContext.Dispose(); } // 辅助方法:转换为SecureString SecureString ConvertToSecureString(string password) { var secureString = new SecureString(); foreach (char c in password) { secureString.AppendChar(c); } return secureString; }
关键注意事项
- 权限要求:应用或用户需要同时拥有SharePoint列表读取权限和Managed Metadata Service术语库读取权限
- 字段内部名称:注意使用字段的内部名称(不是显示名称),可以通过列表设置的字段详情页获取
- 术语递归:如果术语集有多层级子术语,需要递归遍历获取所有术语
内容的提问来源于stack exchange,提问作者2Who
相关产品推荐
相关产品推荐

