我通过客户端对象模型检索内容类型的 FieldCollection:
var fields = contentType.Fields;
clientContext.Load(fields);
clientContext.ExecuteQuery();
然后我循环浏览字段并检查字段是否派生:
if (field.FromBaseType) { ... }
这适用于派生自"项目"的字段"标题",但不适用于内容类型派生自其他自定义内容类型的字段。
为什么FromBaseType
"标题"字段为真,而直接父内容类型的字段则不然?如果派生了一个字段,我怎么知道?
SPField.FromBaseType 属性获取一个布尔值,该值指示字段是否派生自基字段类型,这与确定字段是否派生自父内容类型不同。
以下方法演示如何确定字段的源内容类型:
public static ContentType GetSource(Field field, ContentType contentType)
{
var ctx = field.Context;
var parentCt = contentType.Parent;
ctx.Load(parentCt);
ctx.Load(parentCt.FieldLinks);
ctx.ExecuteQuery();
var fieldLink = parentCt.FieldLinks.FirstOrDefault(fl => fl.Name == field.InternalName);
if (parentCt.StringId != "0x01" && fieldLink != null)
{
return GetSource(field, parentCt);
}
return (fieldLink == null ? contentType : parentCt);
}
用法
var fields = contentType.Fields;
ctx.Load(fields);
ctx.ExecuteQuery();
foreach (var field in fields)
{
var source = GetSource(field, contentType);
Console.WriteLine("Field: {0} Source: {1}",field.Title,source.Name);
}
正如 Vadim 所说,Field.FromBaseType 属性仅指示字段是否派生自基字段类型。它没有说明内容类型。
因此,我也通过加载父内容类型的字段并检查它们是否包含具有相同ID的字段来解决我的问题:
var fields = contentType.Fields;
var parentFields = contentType.Parent.Fields;
clientContext.Load(fields);
clientContext.Load(parentFields);
clientContext.ExecuteQuery();
foreach (var field in fields)
{
if (Enumerable.Any(parentFields, pf => pf.Id == field.Id))
{
// ...
}
}
但这有点粗糙...如果有人有更好的答案,我很乐意接受。