public override void ProvisionObjects(Web web, ProvisioningTemplate template) { Log.Info(Constants.LOGGING_SOURCE_FRAMEWORK_PROVISIONING, CoreResources.Provisioning_ObjectHandlers_ListInstances); if (template.Lists.Any()) { //var parser = new TokenParser(web); if (!web.IsPropertyAvailable("ServerRelativeUrl")) { web.Context.Load(web, w => w.ServerRelativeUrl); web.Context.ExecuteQueryRetry(); } web.Context.Load(web.Lists, lc => lc.IncludeWithDefaultProperties(l => l.RootFolder.ServerRelativeUrl)); web.Context.ExecuteQueryRetry(); var existingLists = web.Lists.AsEnumerable <List>().Select(existingList => existingList.RootFolder.ServerRelativeUrl).ToList(); var serverRelativeUrl = web.ServerRelativeUrl; var createdLists = new List <ListInfo>(); #region Lists foreach (var list in template.Lists) { if (!existingLists.Contains(UrlUtility.Combine(serverRelativeUrl, list.Url))) { var listCreate = new ListCreationInformation(); listCreate.Description = list.Description; listCreate.TemplateType = list.TemplateType; listCreate.Title = list.Title; // the line of code below doesn't add the list to QuickLaunch // the OnQuickLaunch property is re-set on the Created List object listCreate.QuickLaunchOption = list.OnQuickLaunch ? QuickLaunchOptions.On : QuickLaunchOptions.Off; listCreate.Url = list.Url.ToParsedString(); listCreate.TemplateFeatureId = list.TemplateFeatureID; var createdList = web.Lists.Add(listCreate); createdList.Update(); web.Context.Load(createdList, l => l.BaseTemplate); web.Context.ExecuteQueryRetry(); if (!String.IsNullOrEmpty(list.DocumentTemplate)) { createdList.DocumentTemplateUrl = list.DocumentTemplate.ToParsedString(); } // EnableAttachments are not supported for DocumentLibraries and Surveys // TODO: the user should be warned if (createdList.BaseTemplate != (int)ListTemplateType.DocumentLibrary && createdList.BaseTemplate != (int)ListTemplateType.Survey) { createdList.EnableAttachments = list.EnableAttachments; } createdList.EnableModeration = list.EnableModeration; createdList.EnableVersioning = list.EnableVersioning; if (list.EnableVersioning) { createdList.MajorVersionLimit = list.MaxVersionLimit; if (createdList.BaseTemplate == (int)ListTemplateType.DocumentLibrary) { // Only supported on Document Libraries createdList.EnableMinorVersions = list.EnableMinorVersions; if (list.EnableMinorVersions) { createdList.MajorWithMinorVersionsLimit = list.MinorVersionLimit; // Set only if enabled, otherwise you'll get exception due setting value to zero. } } } createdList.OnQuickLaunch = list.OnQuickLaunch; createdList.EnableFolderCreation = list.EnableFolderCreation; createdList.Hidden = list.Hidden; createdList.ContentTypesEnabled = list.ContentTypesEnabled; createdList.Update(); web.Context.Load(createdList.Views); web.Context.Load(createdList, l => l.Id); web.Context.Load(createdList, l => l.RootFolder.ServerRelativeUrl); web.Context.Load(createdList.ContentTypes); web.Context.ExecuteQueryRetry(); // Remove existing content types only if there are custom content type bindings List <Microsoft.SharePoint.Client.ContentType> contentTypesToRemove = new List <Microsoft.SharePoint.Client.ContentType>(); if (list.RemoveExistingContentTypes && list.ContentTypeBindings.Count > 0) { foreach (var ct in createdList.ContentTypes) { contentTypesToRemove.Add(ct); } } ContentTypeBinding defaultCtBinding = null; foreach (var ctBinding in list.ContentTypeBindings) { createdList.AddContentTypeToListById(ctBinding.ContentTypeId, searchContentTypeInSiteHierarchy: true); if (ctBinding.Default) { defaultCtBinding = ctBinding; } } // default ContentTypeBinding should be set last because // list extension .SetDefaultContentTypeToList() re-sets // the list.RootFolder UniqueContentTypeOrder property // which may cause missing CTs from the "New Button" if (defaultCtBinding != null) { createdList.SetDefaultContentTypeToList(defaultCtBinding.ContentTypeId); } // Effectively remove existing content types, if any foreach (var ct in contentTypesToRemove) { ct.DeleteObject(); web.Context.ExecuteQueryRetry(); } createdLists.Add(new ListInfo { CreatedList = createdList, ListInstance = list }); TokenParser.AddToken(new ListIdToken(web, list.Title, createdList.Id)); TokenParser.AddToken(new ListUrlToken(web, list.Title, createdList.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length + 1))); } } #endregion #region Fields foreach (var listInfo in createdLists) { if (listInfo.ListInstance.Fields.Any()) { foreach (var field in listInfo.ListInstance.Fields) { XElement fieldElement = XElement.Parse(field.SchemaXml.ToParsedString()); var id = fieldElement.Attribute("ID").Value; Guid fieldGuid = Guid.Empty; if (Guid.TryParse(id, out fieldGuid)) { if (!listInfo.CreatedList.FieldExistsById(fieldGuid)) { var listIdentifier = fieldElement.Attribute("List") != null?fieldElement.Attribute("List").Value : null; if (listIdentifier != null) { // Temporary remove list attribute from fieldElement fieldElement.Attribute("List").Remove(); } var fieldXml = fieldElement.ToString(); listInfo.CreatedList.Fields.AddFieldAsXml(fieldXml, false, AddFieldOptions.DefaultValue); } } } } listInfo.CreatedList.Update(); web.Context.ExecuteQueryRetry(); } #endregion #region FieldRefs foreach (var listInfo in createdLists) { if (listInfo.ListInstance.FieldRefs.Any()) { foreach (var fieldRef in listInfo.ListInstance.FieldRefs) { var field = web.GetFieldById <Field>(fieldRef.Id); if (!listInfo.CreatedList.FieldExistsById(fieldRef.Id)) { var createdField = listInfo.CreatedList.Fields.Add(field); if (!string.IsNullOrEmpty(fieldRef.DisplayName)) { createdField.Title = fieldRef.DisplayName; } createdField.Hidden = fieldRef.Hidden; createdField.Required = fieldRef.Required; createdField.Update(); } } listInfo.CreatedList.Update(); web.Context.ExecuteQueryRetry(); } } #endregion #region Views foreach (var listInfo in createdLists) { var list = listInfo.ListInstance; var createdList = listInfo.CreatedList; if (list.Views.Any() && list.RemoveExistingViews) { while (createdList.Views.Any()) { createdList.Views[0].DeleteObject(); } web.Context.ExecuteQueryRetry(); } foreach (var view in list.Views) { var viewDoc = XDocument.Parse(view.SchemaXml); var displayNameXml = viewDoc.Root.Attribute("DisplayName"); if (displayNameXml == null) { throw new ApplicationException("Invalid View element, missing a valid value for the attribute DisplayName."); } var viewTitle = displayNameXml.Value; // Type var viewTypeString = viewDoc.Root.Attribute("Type") != null?viewDoc.Root.Attribute("Type").Value : "None"; viewTypeString = viewTypeString[0].ToString().ToUpper() + viewTypeString.Substring(1).ToLower(); var viewType = (ViewType)Enum.Parse(typeof(ViewType), viewTypeString); // Fields string[] viewFields = null; var viewFieldsElement = viewDoc.Descendants("ViewFields").FirstOrDefault(); if (viewFieldsElement != null) { viewFields = (from field in viewDoc.Descendants("ViewFields").Descendants("FieldRef") select field.Attribute("Name").Value).ToArray(); } // Default view var viewDefault = viewDoc.Root.Attribute("DefaultView") != null && Boolean.Parse(viewDoc.Root.Attribute("DefaultView").Value); // Row limit bool viewPaged = true; uint viewRowLimit = 30; var rowLimitElement = viewDoc.Descendants("RowLimit").FirstOrDefault(); if (rowLimitElement != null) { if (rowLimitElement.Attribute("Paged") != null) { viewPaged = bool.Parse(rowLimitElement.Attribute("Paged").Value); } viewRowLimit = uint.Parse(rowLimitElement.Value); } // Query var viewQuery = new StringBuilder(); foreach (var queryElement in viewDoc.Descendants("Query").Elements()) { viewQuery.Append(queryElement.ToString()); } var viewCI = new ViewCreationInformation { ViewFields = viewFields, RowLimit = viewRowLimit, Paged = viewPaged, Title = viewTitle, Query = viewQuery.ToString(), ViewTypeKind = viewType, PersonalView = false, SetAsDefaultView = viewDefault }; createdList.Views.Add(viewCI); createdList.Update(); web.Context.ExecuteQueryRetry(); } // Removing existing views set the OnQuickLaunch option to false and need to be re-set. if (list.OnQuickLaunch && list.RemoveExistingViews && list.Views.Count > 0) { createdList.RefreshLoad(); web.Context.ExecuteQueryRetry(); createdList.OnQuickLaunch = list.OnQuickLaunch; createdList.Update(); web.Context.ExecuteQueryRetry(); } } #endregion #region DataRows foreach (var listInfo in createdLists) { var listInstance = listInfo.ListInstance; if (listInstance.DataRows != null && listInstance.DataRows.Any()) { var list = listInfo.CreatedList; foreach (var dataRow in listInfo.ListInstance.DataRows) { ListItemCreationInformation listitemCI = new ListItemCreationInformation(); var listitem = list.AddItem(listitemCI); foreach (var dataValue in dataRow.Values) { listitem[dataValue.Key.ToParsedString()] = dataValue.Value.ToParsedString(); } listitem.Update(); web.Context.ExecuteQueryRetry(); // TODO: Run in batches? } } } #endregion } }
private List CreateList(Web web, ListInstance list) { var listCreate = new ListCreationInformation(); listCreate.Description = list.Description; listCreate.TemplateType = list.TemplateType; listCreate.Title = list.Title; // the line of code below doesn't add the list to QuickLaunch // the OnQuickLaunch property is re-set on the Created List object listCreate.QuickLaunchOption = list.OnQuickLaunch ? QuickLaunchOptions.On : QuickLaunchOptions.Off; listCreate.Url = list.Url.ToParsedString(); listCreate.TemplateFeatureId = list.TemplateFeatureID; var createdList = web.Lists.Add(listCreate); createdList.Update(); web.Context.Load(createdList, l => l.BaseTemplate); web.Context.ExecuteQueryRetry(); if (!String.IsNullOrEmpty(list.DocumentTemplate)) { createdList.DocumentTemplateUrl = list.DocumentTemplate.ToParsedString(); } // EnableAttachments are not supported for DocumentLibraries and Surveys // TODO: the user should be warned if (createdList.BaseTemplate != (int)ListTemplateType.DocumentLibrary && createdList.BaseTemplate != (int)ListTemplateType.Survey) { createdList.EnableAttachments = list.EnableAttachments; } createdList.EnableModeration = list.EnableModeration; createdList.EnableVersioning = list.EnableVersioning; if (list.EnableVersioning) { createdList.MajorVersionLimit = list.MaxVersionLimit; if (createdList.BaseTemplate == (int)ListTemplateType.DocumentLibrary) { // Only supported on Document Libraries createdList.EnableMinorVersions = list.EnableMinorVersions; createdList.DraftVersionVisibility = (DraftVisibilityType)list.DraftVersionVisibility; if (list.EnableMinorVersions) { createdList.MajorWithMinorVersionsLimit = list.MinorVersionLimit; // Set only if enabled, otherwise you'll get exception due setting value to zero. // DraftVisibilityType.Approver is available only when the EnableModeration option of the list is true if (DraftVisibilityType.Approver == (DraftVisibilityType)list.DraftVersionVisibility) { if (list.EnableModeration) { createdList.DraftVersionVisibility = (DraftVisibilityType)list.DraftVersionVisibility; } else { WriteWarning("DraftVersionVisibility not applied because EnableModeration is not set to true", ProvisioningMessageType.Warning); } } else { createdList.DraftVersionVisibility = (DraftVisibilityType)list.DraftVersionVisibility; } } } } createdList.OnQuickLaunch = list.OnQuickLaunch; if (createdList.BaseTemplate != (int)ListTemplateType.DiscussionBoard) { createdList.EnableFolderCreation = list.EnableFolderCreation; } createdList.Hidden = list.Hidden; createdList.ContentTypesEnabled = list.ContentTypesEnabled; createdList.Update(); web.Context.Load(createdList.Views); web.Context.Load(createdList, l => l.Id); web.Context.Load(createdList, l => l.RootFolder.ServerRelativeUrl); web.Context.Load(createdList.ContentTypes); web.Context.ExecuteQueryRetry(); // Remove existing content types only if there are custom content type bindings var contentTypesToRemove = new List <ContentType>(); if (list.RemoveExistingContentTypes && list.ContentTypeBindings.Count > 0) { contentTypesToRemove.AddRange(createdList.ContentTypes); } ContentTypeBinding defaultCtBinding = null; foreach (var ctBinding in list.ContentTypeBindings) { createdList.AddContentTypeToListById(ctBinding.ContentTypeId, searchContentTypeInSiteHierarchy: true); if (ctBinding.Default) { defaultCtBinding = ctBinding; } } // default ContentTypeBinding should be set last because // list extension .SetDefaultContentTypeToList() re-sets // the list.RootFolder UniqueContentTypeOrder property // which may cause missing CTs from the "New Button" if (defaultCtBinding != null) { createdList.SetDefaultContentTypeToList(defaultCtBinding.ContentTypeId); } // Effectively remove existing content types, if any foreach (var ct in contentTypesToRemove) { ct.DeleteObject(); web.Context.ExecuteQueryRetry(); } return(createdList); }