Add list from schema Xml by client object model

29/01/2014 18:10

Actually in this snippet not really schema.xml is used, but only as xml source file, what is easy to get from visual studio.

Sharepoint Apps have standard way to deploy list, but this code was used for console application - create more lists without any deployment or features.

 

Following changes (in first row only) are needed in schema.xml file to work my code (original is commented out and information from Elements.xml are added)

<!--<List xmlns:ows="Microsoft SharePoint" Title="Site Collection Repository" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/SiteCollectionRepository" BaseType="0" xmlns="https://schemas.microsoft.com/sharepoint/">-->
<List Title="Site Collection Repository" Url="SiteCollectionRepository" Description="Základný zoznam pre uloženie vlastností kolekcie lokalít" ListTemplateType="103" OnQuickLaunch="TRUE">
 
Function:
 
   public static void AddListFromSchema(string webUrl, string schemaXmlPath)
        {
            //read document
            XDocument doc = XDocument.Load(schemaXmlPath);
            XElement root = doc.Root;
 
            //get basic list attributes
            string listName = root.Attribute("Title").Value;
            string listUrl = root.Attribute("Url").Value;
            int listTemplateType = Convert.ToInt32(root.Attribute("ListTemplateType").Value);
            bool listQuickLaunch = Convert.ToBoolean(root.Attribute("OnQuickLaunch").Value);
            string listDescription = root.Attribute("Description").Value;
 
            //get fields
            IEnumerable<XElement> xFields = root.Elements("MetaData").Elements("Fields").Elements("Field");
 
            if (string.IsNullOrEmpty(webUrl) || string.IsNullOrEmpty(listUrl))
            {
                throw new ArgumentNullException("webUrl or listUrl cannot be empty");
            }
            else if (string.IsNullOrEmpty(listName))
            {
                listName = listUrl;
            }
 
            ClientContext context = new ClientContext(webUrl);
            Web web = context.Web;
            IEnumerable<List> result = context.LoadQuery(web.Lists.Include(myList => myList.Title,
                                                                                     myList => myList.Id,
                                                                                     myList => myList.DefaultDisplayFormUrl
                                                                                     ));
            context.ExecuteQuery();
 
 
            //Create list if doesn't exist
            List list = result.FirstOrDefault(myList => myList.Title == listName);
            if (list == null)
            {
                ListCreationInformation creationInfo = new ListCreationInformation();
                
                creationInfo.Title = listName;
                creationInfo.Url = listUrl;
                creationInfo.TemplateType = listTemplateType;
                list = web.Lists.Add(creationInfo);
                list.Description = listDescription;
                list.OnQuickLaunch = listQuickLaunch;
                
                list.Update();
 
                context.ExecuteQuery();
            }
 
            //Add fields
            foreach (XElement xField in xFields)
            {
                string fldName = xField.Attribute("Name").Value;
                string fldDisplayName = xField.Attribute("DisplayName").Value;
 
                IEnumerable<Field> fields = context.LoadQuery(list.Fields.Include(f => f.InternalName));
                context.ExecuteQuery();
 
                Field existingField = fields.FirstOrDefault(f => f.InternalName == fldName);
                if (existingField == null)
                {
                    string fieldXml = Regex.Replace(xField.ToString(), fldDisplayName, fldName);
 
                    //internal name is derived from 'DisplayName' ('InternalName' attribute not working), DisplayName is overriden later as 'Title'
                    Field fld = list.Fields.AddFieldAsXml(fieldXml, true, AddFieldOptions.DefaultValue);
                    fld.Title = fldDisplayName;
 
                    fld.Update();
                    context.ExecuteQuery();
                }
            }
        }