文档库模板示例 SharePoint 外接程序
ECM.DocumentLibraries 示例展示了如何使用提供程序托管加载项创建列表或文档库,向它分配内容类型,并删除默认内容类型。
如果需要执行以下操作,请使用此解决方案:
- 创建列表或文档库,并应用默认内容类型。
- 对自定义字段的本地化版本的添加、维护或实现加强控制。
- 删除列表或库上的默认内容类型。
- 创建列表或库时应用库配置设置。
准备工作
若要开始,请从 GitHub 上的 Office 365 开发人员模式和做法项目下载 ECM.DocumentLibraries 示例外接程序。
注意
本文中的代码按原样提供,不提供任何明示或暗示的担保,包括对特定用途适用性、适销性或不侵权的默示担保。
访问 ECM.DocumentLibraries 示例外接程序的用户必须具有管理列表的权限。 Default.aspx.cs 中的 DoesUserHavePermission 方法检查用户的权限,以确保它们可以管理列表。 如果用户没有管理列表的权限,则外接程序会向用户显示错误消息。
private bool DoesUserHavePermission()
{
var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
using (var ctx = spContext.CreateUserClientContextForSPHost())
{
BasePermissions perms = new BasePermissions();
perms.Set(PermissionKind.ManageLists);
ClientResult<bool> _permResult = ctx.Web.DoesUserHavePermissions(perms);
ctx.ExecuteQuery();
return _permResult.Value;
}
}
使用 ECM.DocumentLibraries 示例外接程序
当你启动此外接程序时,起始页面将如下图所示。 选择“网站内容”>“添加应用”>“文档库”>“高级选项”时,ECM.DocumentLibraries 起始页将与添加新文档库的页面类似,只有一点不同。 启动外接程序时,“文档模板”列表将显示自定义文档库模板、IT 文档和 Contoso 文档。 如果用户选择“创建”,选定自定义内容类型便会分配到新文档库。
ECM.DocumentLibraries 示例外接程序的起始页
当用户选择“创建”时,Default.aspx.cs 中的 CreateLibrary_Click 方法将检查所选的默认模板,并调用 ContentTypeManager.cs 中的 CreateITDocumentLibrary 或 CreateContosoDocumentLibrary 方法,如以下代码中所示。
protected void CreateLibrary_Click(object sender, EventArgs e)
{
try
{
var _spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
var _templateSelectedItem = this.DocumentTemplateType.Value;
var _libraryToCreate = this.GetLibraryToCreate();
using (var _ctx = _spContext.CreateUserClientContextForSPHost())
{
_ctx.ApplicationName = "AMS ECM.DocumentLibraries";
ContentTypeManager _manager = new ContentTypeManager();
switch(_templateSelectedItem)
{
case "IT Document":
_manager.CreateITDocumentLibrary(_ctx, _libraryToCreate);
break;
case "Contoso Document":
_manager.CreateContosoDocumentLibrary(_ctx, _libraryToCreate);
break;
}
}
Response.Redirect(this.Url.Value);
}
catch (Exception _ex)
{
throw;
}
}
然后,CreateContosoDocumentLibrary 方法执行下列任务,如下一个代码示例所示:
- 在 Managed Metadata Service 中创建自定义字段。
- 创建内容类型。
- 将自定义字段与内容类型相关联。
- 创建包含内容类型的文档库。
public void CreateContosoDocumentLibrary(ClientContext ctx, Library library)
{
// Check the fields.
if (!ctx.Web.FieldExistsById(FLD_CLASSIFICATION_ID)){
ctx.Web.CreateTaxonomyField(FLD_CLASSIFICATION_ID,
FLD_CLASSIFICATION_INTERNAL_NAME,
FLD_CLASSIFICATION_DISPLAY_NAME,
FIELDS_GROUP_NAME,
TAXONOMY_GROUP,
TAXONOMY_TERMSET_CLASSIFICATION_NAME);
}
// Check the content type.
if (!ctx.Web.ContentTypeExistsById(CONTOSODOCUMENT_CT_ID)){
ctx.Web.CreateContentType(CONTOSODOCUMENT_CT_NAME,
CT_DESC, CONTOSODOCUMENT_CT_ID,
CT_GROUP);
}
// Associate fields to content types.
if (!ctx.Web.FieldExistsByNameInContentType(CONTOSODOCUMENT_CT_NAME, FLD_CLASSIFICATION_INTERNAL_NAME)){
ctx.Web.AddFieldToContentTypeById(CONTOSODOCUMENT_CT_ID,
FLD_CLASSIFICATION_ID.ToString(),
false);
}
CreateLibrary(ctx, library, CONTOSODOCUMENT_CT_ID);
}
CreateContosoDocumentLibrary 调用 CreateTaxonomyField 方法,这是 OfficeDevPnP.Core 的一部分。 CreateTaxonomyField 从提供程序托管的外接程序中的托管元数据服务创建字段。
public static Field CreateTaxonomyField(this Web web, Guid id, string internalName, string displayName, string group, TermSet termSet, bool multiValue = false)
{
internalName.ValidateNotNullOrEmpty("internalName");
displayName.ValidateNotNullOrEmpty("displayName");
termSet.ValidateNotNullOrEmpty("termSet");
try
{
var _field = web.CreateField(id, internalName, multiValue ? "TaxonomyFieldTypeMulti" : "TaxonomyFieldType", true, displayName, group, "ShowField=\"Term1033\"");
WireUpTaxonomyField(web, _field, termSet, multiValue);
_field.Update();
web.Context.ExecuteQuery();
return _field;
}
catch (Exception)
{
/// If there is an exception, the hidden field might be present.
FieldCollection _fields = web.Fields;
web.Context.Load(_fields, fc => fc.Include(f => f.Id, f => f.InternalName));
web.Context.ExecuteQuery();
var _hiddenField = id.ToString().Replace("-", "");
var _field = _fields.FirstOrDefault(f => f.InternalName == _hiddenField);
if (_field != null)
{
_field.DeleteObject();
web.Context.ExecuteQuery();
}
throw;
}
}
CreateContosoDocumentLibrary 调用 OfficeDevPnP.Core 中的 CreateContentType 方法。 CreateContentType 将创建新的内容类型。
public static ContentType CreateContentType(this Web web, string name, string description, string id, string group, ContentType parentContentType = null)
{
LoggingUtility.Internal.TraceInformation((int)EventId.CreateContentType, CoreResources.FieldAndContentTypeExtensions_CreateContentType01, name, id);
// Load the current collection of content types.
ContentTypeCollection contentTypes = web.ContentTypes;
web.Context.Load(contentTypes);
web.Context.ExecuteQuery();
ContentTypeCreationInformation newCt = new ContentTypeCreationInformation();
// Set the properties for the content type.
newCt.Name = name;
newCt.Id = id;
newCt.Description = description;
newCt.Group = group;
newCt.ParentContentType = parentContentType;
ContentType myContentType = contentTypes.Add(newCt);
web.Context.ExecuteQuery();
// Return the content type object.
return myContentType;
}
CreateContosoDocumentLibrary 调用 AddFieldToContentTypeById 方法,这是 OfficeDevPnP.Core 的一部分。 AddFieldToContentTypeById 将字段与内容类型相关联。
public static void AddFieldToContentTypeById(this Web web, string contentTypeID, string fieldID, bool required = false, bool hidden = false)
{
// Get content type.
ContentType ct = web.GetContentTypeById(contentTypeID);
web.Context.Load(ct);
web.Context.Load(ct.FieldLinks);
web.Context.ExecuteQuery();
// Get field.
Field fld = web.Fields.GetById(new Guid(fieldID));
// Add field association to content type.
AddFieldToContentType(web, ct, fld, required, hidden);
}
CreateContosoDocumentLibrary 调用 ContentTypeManager.cs 中的 CreateLibrary 方法,以创建文档库。 CreateLibrary 方法分配库设置,如文档库的描述、文档版本控制和相关的内容类型。
private void CreateLibrary(ClientContext ctx, Library library, string associateContentTypeID)
{
if (!ctx.Web.ListExists(library.Title))
{
ctx.Web.AddList(ListTemplateType.DocumentLibrary, library.Title, false);
List _list = ctx.Web.GetListByTitle(library.Title);
if(!string.IsNullOrEmpty(library.Description)) {
_list.Description = library.Description;
}
if(library.VerisioningEnabled) {
_list.EnableVersioning = true;
}
_list.ContentTypesEnabled = true;
_list.Update();
ctx.Web.AddContentTypeToListById(library.Title, associateContentTypeID, true);
// Remove the default Document Content Type.
_list.RemoveContentTypeByName(ContentTypeManager.DEFAULT_DOCUMENT_CT_NAME);
ctx.Web.Context.ExecuteQuery();
}
else
{
throw new Exception("A list, survey, discussion board, or document library with the specified title already exists in this website. Please choose another title.");
}
}
CreateLibrary 调用 ListExtensions.cs 中的 RemoveContentTypeByName ,这是 OfficeDevPnP.Core 的一部分。 RemoveContentTypeByName 将删除文档库上的默认内容类型。
public static void RemoveContentTypeByName(this List list, string contentTypeName)
{
if (string.IsNullOrEmpty(contentTypeName))
{
throw (contentTypeName == null)
? new ArgumentNullException("contentTypeName")
: new ArgumentException(CoreResources.Exception_Message_EmptyString_Arg, "contentTypeName");
}
ContentTypeCollection _cts = list.ContentTypes;
list.Context.Load(_cts);
IEnumerable<ContentType> _results = list.Context.LoadQuery<ContentType>(_cts.Where(item => item.Name == contentTypeName));
list.Context.ExecuteQuery();
ContentType _ct = _results.FirstOrDefault();
if (_ct != null)
{
_ct.DeleteObject();
list.Update();
list.Context.ExecuteQuery();
}
}
创建文档库后,转到文档库上的“库设置”,以检查外接程序分配给文档库的名称、描述、文档版本控制设置、内容类型和自定义字段。
外接程序应用的库设置