private static string ReplaceTaxonomyTokens(ClientContext ctx, Web web, string schemaXml) { var tokens = new List <string>() { "{@DefaultValue:", "{@SspId}", "{@TermSet:", "{@AnchorTermId:" }; var foundTokens = tokens.Where(t => schemaXml.Contains(t)).ToList(); if (foundTokens.Count == 0) { return(schemaXml); } var taxonomySession = TaxonomySession.GetTaxonomySession(ctx); var termStore = TermStoreUtility.GetTermStore(ctx, taxonomySession); ctx.Load(termStore, ts => ts.Id); ctx.ExecuteQueryRetry(); schemaXml = schemaXml.Replace("{@SspId}", termStore.Id.ToString()); var termSetName = schemaXml.GetInnerText("{@TermSet:", "}"); if (!string.IsNullOrEmpty(termSetName)) { var termSets = termStore.GetTermSetsByName(termSetName, (int)web.Language); ctx.Load(termSets, ts => ts.Include(t => t.Id, t => t.Name)); ctx.ExecuteQueryRetry(); if (termSets.Count == 0) { throw new InvalidOperationException($"Unable to find term set {termSetName}."); } var termSet = GetCorrectTermSet(ctx, schemaXml, termSets); System.Diagnostics.Debug.WriteLine($"{schemaXml.GetXmlAttribute("DisplayName")} | {termSet.Id} | {termSet.Name}"); schemaXml = schemaXml.Replace($"{{@TermSet:{termSetName}}}", termSet.Id.ToString()); var terms = termSet.GetAllTerms(); ctx.Load(terms); ctx.ExecuteQueryRetry(); if (foundTokens.Contains("{@AnchorTermId:")) { var anchorTermName = schemaXml.GetInnerText("{@AnchorTermId:", "}"); var foundAnchorTerm = terms.FirstOrDefault(t => t.Name == anchorTermName); schemaXml = schemaXml.Replace($"{{@AnchorTermId:{anchorTermName}}}", foundAnchorTerm?.Id.ToString() ?? ""); } if (foundTokens.Contains("{@DefaultValue:")) { var defaultValueTermName = schemaXml.GetInnerText("{@DefaultValue:", "}"); var foundDefaultTerm = terms.FirstOrDefault(t => t.Name == defaultValueTermName); schemaXml = schemaXml.Replace($"{{@DefaultValue:{defaultValueTermName}}}", foundDefaultTerm != null ? $"-1;#{defaultValueTermName}|{foundDefaultTerm.Id.ToString()}" : ""); } } return(schemaXml); }
private void UpdateListItem(ClientContext ctx, Web web) { if (ListItemFieldValues == null || ListItemFieldValues.Count == 0) { return; } var rootWeb = ctx.Site.RootWeb; rootWeb.EnsureProperties(w => w.Url, w => w.ServerRelativeUrl); var specialTypes = new List <string>() { "Lookup", "DateTime", "User", "TaxonomyFieldType", "TaxonomyFieldTypeMulti" }; var specialNames = new List <string>() { "ContentTypeId", "ContentType", WikiPageContentFieldName, //Should ignore, set elsewhere PublishingPageContentFieldName //Should ignore, set elsewhere }; var item = File.ListItemAllFields; TaxonomySession taxonomySession = null; TermStore termStore = null; ClientContext tempCtx = ctx.Clone(web.Url); var library = tempCtx.Web.Lists.GetByTitle(List); tempCtx.Load(library, l => l.ContentTypes, l => l.Fields); tempCtx.ExecuteQueryRetry(); if (ListItemFieldValues.FirstOrDefault(fv => fv.FieldType != null && fv.FieldType.StartsWith("TaxonomyField")) != null) { taxonomySession = TaxonomySession.GetTaxonomySession(tempCtx); termStore = TermStoreUtility.GetTermStore(tempCtx, taxonomySession); } var lookupFields = library.Fields.Where(f => f.FieldTypeKind == FieldType.Lookup && ListItemFieldValues.FirstOrDefault(fv => fv.FieldName == f.InternalName) != null); var lookupQueries = new Dictionary <string, string[]>(); foreach (var field in lookupFields) { var lookupField = tempCtx.CastTo <FieldLookup>(field); lookupField.EnsureProperties(lf => lf.LookupList, lf => lf.LookupField); var lookupListId = lookupField.LookupList; var lookupList = tempCtx.Web.Lists.GetById(Guid.Parse(lookupListId)); tempCtx.Load(lookupList, l => l.Title); try { tempCtx.ExecuteQueryRetry(); } catch { //Ignore } lookupQueries[field.InternalName] = new string[] { lookupList.Title, $"<View><ViewFields><FieldRef Name='{lookupField.LookupField}'/></ViewFields><Query><Where><Contains><FieldRef Name='{lookupField.LookupField}' /><Value Type='Text'>#VALUE#</Value></Contains></Where></Query><RowLimit>1</RowLimit></View>" }; } foreach (var fieldInfo in ListItemFieldValues) { if (!specialNames.Contains(fieldInfo.FieldName) && !specialTypes.Contains(fieldInfo.FieldType)) { item[fieldInfo.FieldName] = fieldInfo.Value.Replace("{@WebUrl}", web.Url) .Replace("{@WebServerRelativeUrl}", web.ServerRelativeUrl) .Replace("{@SiteUrl}", rootWeb.Url) .Replace("{@SiteServerRelativeUrl}", rootWeb.ServerRelativeUrl); } else if (fieldInfo.FieldType == "DateTime") { item[fieldInfo.FieldName] = DateTime.ParseExact(fieldInfo.Value, "yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture); } else if (fieldInfo.FieldType == "User") { try { var user = tempCtx.Web.EnsureUser(fieldInfo.Value); tempCtx.Load(user); tempCtx.ExecuteQueryRetry(); item[fieldInfo.FieldName] = user.Id; } catch { //ignore //TODO: Notification event } } else if (fieldInfo.FieldType == "Lookup") { if (lookupQueries.ContainsKey(fieldInfo.FieldName)) { var lookupListTitle = lookupQueries[fieldInfo.FieldName][0]; var viewXml = lookupQueries[fieldInfo.FieldName][1].Replace( "#VALUE#", fieldInfo.Value); var lookupList = tempCtx.Web.Lists.GetByTitle(lookupListTitle); var query = new CamlQuery(); query.ViewXml = viewXml; var listItems = lookupList.GetItems(query); tempCtx.Load(listItems); try { tempCtx.ExecuteQueryRetry(); if (listItems.Count == 0) { //TODO: Notify } else { item[fieldInfo.FieldName] = listItems[0].Id; } } catch (Exception ex) { //TODO: Notify //OnNotify(ProvisioningNotificationLevels.Verbose, $"Unable to find {fieldInfo.Value} in {lookupListTitle}. An exception occurred: {ex.Message}. Skipping attempt to set list item value."); } } } else if (fieldInfo.FieldType != null && fieldInfo.FieldType.StartsWith("TaxonomyField")) { tempCtx.Web.EnsureProperty(w => w.Language); var termSetName = fieldInfo.Value.GetInnerText("{@TermSet:", "}"); var termNames = fieldInfo.Value.GetInnerText("{@Terms:", "}").Split(';'); var termSets = termStore.GetTermSetsByName(termSetName, (int)tempCtx.Web.Language); tempCtx.Load(termSets, ts => ts.Include(t => t.Id)); tempCtx.ExecuteQueryRetry(); if (termSets.Count == 0) { //OnNotify(ProvisioningNotificationLevels.Verbose, // $"Unable to find term set {termSetName}. Skipping list item field!"); } else if (termNames.Length == 0) { //OnNotify(ProvisioningNotificationLevels.Verbose, // $"Bad field value token {fieldInfo.Value}. Skipping list item field!"); } else { var termSet = GetCorrectTermSet(ctx, termNames[0], termSets); var terms = termSet.GetAllTerms(); tempCtx.Load(terms); tempCtx.ExecuteQueryRetry(); var fieldValue = string.Empty; for (var c = 0; c < termNames.Length; c++) { var termName = termNames[c]; var foundTerm = terms.FirstOrDefault(t => t.Name == termName); if (foundTerm == null) { //OnNotify(ProvisioningNotificationLevels.Verbose, $"Unable to find term {termName}. Skipping list item field!"); break; } if (fieldValue != String.Empty) { fieldValue = fieldValue + ";"; } if (termNames.Length == 1) { fieldValue = $"-1;#{termName}|{foundTerm.Id}"; } else { fieldValue = fieldValue + $"{termName}|{foundTerm.Id}"; } } if (fieldValue != String.Empty) { item[fieldInfo.FieldName] = fieldValue; } } } else if (fieldInfo.FieldName == "ContentType") { var itemCType = library.ContentTypes.FirstOrDefault(ctype => ctype.Name == fieldInfo.Value); if (itemCType == null) { throw new InvalidOperationException( $"Content type {fieldInfo.Value} not found in list. Unable to add item."); } else { item["ContentTypeId"] = itemCType.Id; } } } item.Update(); }
private static string TokenizeTaxonomyField(ClientContext ctx, Field field, string schemaXml) { var fieldType = schemaXml.GetXmlAttribute("Type"); if (!fieldType.StartsWith("TaxonomyField")) { return(schemaXml); } schemaXml = schemaXml.RemoveXmlAttribute("List"); schemaXml = schemaXml.RemoveXmlAttribute("WebId"); schemaXml = schemaXml.RemoveXmlAttribute("SourceID"); schemaXml = schemaXml.RemoveXmlAttribute("Version"); //Default Value var taxonomyField = ctx.CastTo <TaxonomyField>(field); ctx.Load(taxonomyField); ctx.ExecuteQueryRetry(); var defaultValue = taxonomyField.DefaultValue; if (!string.IsNullOrEmpty(defaultValue)) { schemaXml = schemaXml.Replace(defaultValue, ""); } var sspId = taxonomyField.SspId.ToString(); schemaXml = schemaXml.Replace(sspId, "{@SspId}"); if (taxonomyField.TermSetId != default(Guid) || taxonomyField.AnchorId != default(Guid)) { var taxonomySession = TaxonomySession.GetTaxonomySession(ctx); var termStore = TermStoreUtility.GetTermStore(ctx, taxonomySession); TermSet termSet = null; Term anchorTerm = null; if (taxonomyField.TermSetId != default(Guid)) { termSet = termStore.GetTermSet(taxonomyField.TermSetId); ctx.Load(termSet, ts => ts.Name); } if (taxonomyField.AnchorId != default(Guid)) { anchorTerm = termStore.GetTerm(taxonomyField.AnchorId); ctx.Load(anchorTerm, t => t.Name); } try { ctx.ExecuteQueryRetry(); } catch { //ignore } if (termSet != null && termSet.IsPropertyAvailable("Name")) { schemaXml = schemaXml.Replace(taxonomyField.TermSetId.ToString(), $"{{@TermSet:{termSet.Name}}}"); } else { schemaXml = schemaXml.Replace(taxonomyField.TermSetId.ToString(), $"00000000-0000-0000-0000-000000000000"); } if (anchorTerm != null && anchorTerm.IsPropertyAvailable("Name")) { schemaXml = schemaXml.Replace(taxonomyField.AnchorId.ToString(), $"{{@AnchorTermId:{anchorTerm.Name}}}"); } else { schemaXml = schemaXml.Replace(taxonomyField.AnchorId.ToString(), $"00000000-0000-0000-0000-000000000000"); } } return(schemaXml); }
private void AddAndDeleteListItems() { var batchSize = 100; var creatorsWithItems = Creators.Values.Where(l => l.ProvisionListItems && l.ListItems != null && l.ListItems.Count > 0).ToList(); var creatorsWithListItemsToClear = Creators.Values.Where(l => l.DeleteExistingListItems).ToList(); if (creatorsWithListItemsToClear.Count > 0) { DeleteExistingItems(creatorsWithListItemsToClear, batchSize); } if (creatorsWithItems.Count == 0) { return; } var creatorsWithLookups = creatorsWithItems.Where( c => c.ListItems.FirstOrDefault(i => i.FieldValues.FirstOrDefault(li => li.FieldType == "Lookup") != null) != null).ToList(); List <ListCreator> sortedCreators; Dictionary <string, Dictionary <string, string[]> > lookupQueries = new Dictionary <string, Dictionary <string, string[]> >(); if (creatorsWithLookups.Count == 0) { sortedCreators = creatorsWithItems; } else { sortedCreators = new List <ListCreator>(); //Add the ones with no lookup fields first, it doesn't matter what order they go in foreach (var creatorWithItems in creatorsWithItems) { if (!creatorsWithLookups.Contains(creatorWithItems)) { sortedCreators.Add(creatorWithItems); } } //Note that this approach doesn't deal with circular relationships, //but there's not really much that can be done in that case other than make mutliple passes //so, if you need it, you'll need to write it! foreach (var creatorWithLookups in creatorsWithLookups) { var lookupFields = creatorWithLookups.List.Fields.Where(f => creatorWithLookups.ListItems[0].FieldValues.FirstOrDefault(li => li.FieldName == f.InternalName && li.FieldType == "Lookup") != null); foreach (var field in lookupFields) { var lookupField = _ctx.CastTo <FieldLookup>(field); lookupField.EnsureProperties(lf => lf.LookupList, lf => lf.LookupField); var lookupListId = lookupField.LookupList; var lookupList = _web.Lists.GetById(Guid.Parse(lookupListId)); _ctx.Load(lookupList, l => l.Title); try { _ctx.ExecuteQueryRetry(); } catch { //Ignore } if (Creators.ContainsKey(lookupList.Title) && !sortedCreators.Contains(Creators[lookupList.Title]) && creatorsWithItems.Contains(Creators[lookupList.Title])) { sortedCreators.Add(Creators[lookupList.Title]); } if (!lookupQueries.ContainsKey(creatorWithLookups.Title)) { lookupQueries[creatorWithLookups.Title] = new Dictionary <string, string[]>(); } lookupQueries[creatorWithLookups.Title][field.InternalName] = new string[] { lookupList.Title, $"<View><ViewFields><FieldRef Name='{lookupField.LookupField}'/></ViewFields><Query><Where><Contains><FieldRef Name='{lookupField.LookupField}' /><Value Type='Text'>#VALUE#</Value></Contains></Where></Query><RowLimit>1</RowLimit></View>" }; } sortedCreators.Add(creatorWithLookups); } } TaxonomySession taxonomySession = null; TermStore termStore = null; ClientContext tempCtx = _ctx.Clone(_web.Url); if (sortedCreators.FirstOrDefault(c => c.ListItems.FirstOrDefault(li => li.FieldValues.FirstOrDefault(fv => fv.FieldType != null && fv.FieldType.StartsWith("TaxonomyField")) != null) != null) != null) { taxonomySession = TaxonomySession.GetTaxonomySession(tempCtx); termStore = TermStoreUtility.GetTermStore(tempCtx, taxonomySession); } foreach (var creator in sortedCreators) { if (creator.ProvisionListItems && creator.ListItems != null) { OnNotify(ProvisioningNotificationLevels.Verbose, "Creating items for " + creator.Title); creator.List.ContentTypes.EnsureProperties(cts => cts.Include(ct => ct.Id, ct => ct.Name)); var specialTypes = new List <string>() { "Lookup", "DateTime", "User", "TaxonomyFieldType", "TaxonomyFieldTypeMulti" }; var specialNames = new List <string>() { "ContentTypeId", "ContentType" }; for (var i = 0; i < creator.ListItems.Count; i++) { var newItemInfo = creator.ListItems[i]; var item = creator.List.AddItem(new ListItemCreationInformation()); foreach (var fieldInfo in newItemInfo.FieldValues) { if (!specialNames.Contains(fieldInfo.FieldName) && !specialTypes.Contains(fieldInfo.FieldType)) { item[fieldInfo.FieldName] = fieldInfo.Value.Replace("{@WebUrl}", _web.Url).Replace("{@WebServerRelativeUrl}", _web.ServerRelativeUrl); } else if (fieldInfo.FieldType == "DateTime") { item[fieldInfo.FieldName] = DateTime.ParseExact(fieldInfo.Value, "yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture); } else if (fieldInfo.FieldType == "User") { try { var user = tempCtx.Web.EnsureUser(fieldInfo.Value); tempCtx.Load(user); tempCtx.ExecuteQueryRetry(); item[fieldInfo.FieldName] = user.Id; } catch { OnNotify(ProvisioningNotificationLevels.Verbose, $"Unable to ensure user {fieldInfo.Value}. Adding the list item, but leaving the field blank!"); } } else if (fieldInfo.FieldType == "Lookup") { if (lookupQueries.ContainsKey(creator.Title) && lookupQueries[creator.Title].ContainsKey(fieldInfo.FieldName)) { var lookupListTitle = lookupQueries[creator.Title][fieldInfo.FieldName][0]; var viewXml = lookupQueries[creator.Title][fieldInfo.FieldName][1].Replace( "#VALUE#", fieldInfo.Value); var lookupList = tempCtx.Web.Lists.GetByTitle(lookupListTitle); var query = new CamlQuery(); query.ViewXml = viewXml; var listItems = lookupList.GetItems(query); tempCtx.Load(listItems); try { tempCtx.ExecuteQueryRetry(); if (listItems.Count == 0) { OnNotify(ProvisioningNotificationLevels.Verbose, $"Unable to find {fieldInfo.Value} in {lookupListTitle}. Skipping attempt to set list item value."); } else { item[fieldInfo.FieldName] = listItems[0].Id; } } catch (Exception ex) { OnNotify(ProvisioningNotificationLevels.Verbose, $"Unable to find {fieldInfo.Value} in {lookupListTitle}. An exception occurred: {ex.Message}. Skipping attempt to set list item value."); } } else { OnNotify(ProvisioningNotificationLevels.Verbose, $"Bad data for lookup field {fieldInfo.FieldName}. Skipping attempt to set list item value."); } } else if (fieldInfo.FieldType != null && fieldInfo.FieldType.StartsWith("TaxonomyField")) { var termSetName = fieldInfo.Value.GetInnerText("{@TermSet:", "}"); var termNames = fieldInfo.Value.GetInnerText("{@Terms:", "}").Split(';'); var termSets = termStore.GetTermSetsByName(termSetName, (int)_web.Language); tempCtx.Load(termSets, ts => ts.Include(t => t.Id)); tempCtx.ExecuteQueryRetry(); if (termSets.Count == 0) { OnNotify(ProvisioningNotificationLevels.Verbose, $"Unable to find term set {termSetName}. Skipping list item field!"); } else if (termNames.Length == 0) { OnNotify(ProvisioningNotificationLevels.Verbose, $"Bad field value token {fieldInfo.Value}. Skipping list item field!"); } else { var terms = termSets[0].GetAllTerms(); tempCtx.Load(terms); tempCtx.ExecuteQueryRetry(); var fieldValue = string.Empty; for (var c = 0; c < termNames.Length; c++) { var termName = termNames[c]; var foundTerm = terms.FirstOrDefault(t => t.Name == termName); if (foundTerm == null) { OnNotify(ProvisioningNotificationLevels.Verbose, $"Unable to find term {termName}. Skipping list item field!"); break; } if (fieldValue != String.Empty) { fieldValue = fieldValue + ";"; } if (termNames.Length == 1) { fieldValue = $"-1;#{termName}|{foundTerm.Id}"; } else { fieldValue = fieldValue + $"{termName}|{foundTerm.Id}"; } } if (fieldValue != String.Empty) { item[fieldInfo.FieldName] = fieldValue; } } } else if (fieldInfo.FieldName == "ContentType" && creator.ContentType.ToLowerInvariant() != fieldInfo.Value.ToLowerInvariant()) { var itemCType = creator.List.ContentTypes.FirstOrDefault(ctype => ctype.Name == fieldInfo.Value); if (itemCType == null) { throw new InvalidOperationException( $"Content type {fieldInfo.Value} not found in list. Unable to add item."); } else { item["ContentTypeId"] = itemCType.Id; } } } item.Update(); if (i % batchSize == 0) { _ctx.ExecuteQueryRetry(); } } _ctx.ExecuteQueryRetry(); } } }