文档库模板示例 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 示例外接程序的起始页

显示 ECM.DocumentLibraries 示例外接程序起始页的屏幕截图,其中“文档模板”下拉框列出了“IT 文档”选项。


当用户选择“创建”时,Default.aspx.cs 中的 CreateLibrary_Click 方法将检查所选的默认模板,并调用 ContentTypeManager.cs 中的 CreateITDocumentLibraryCreateContosoDocumentLibrary 方法,如以下代码中所示。

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();
            }
        }

创建文档库后,转到文档库上的“库设置”,以检查外接程序分配给文档库的名称、描述、文档版本控制设置、内容类型和自定义字段。

外接程序应用的库设置

“文档库设置”页的屏幕截图,其中突出显示了“名称”、“Web 地址”和“说明”字段。

另请参阅