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);
        }
Пример #2
0
        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);
        }
Пример #4
0
        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();
                }
            }
        }