It’s been a while that we’ve been developing SharePoint Provider Hosted apps and one of the problems that happens most of the time is that you need update the app for SharePoint and add the new lists without lose any data from others existing lists.

Basically, if you publish one SharePoint Provider hosted app with a set of customs lists, and in the future, if you try update your app with more custom lists you have the option of this list to appear on your application:

  • One of these options, is to remove your app on your SharePoint Web and then re- install again.

On this situation, all data that the application been collecting along the time is removed and probably your customer needs to press the red bottom for call all firemen’s to help him to rescue the data.

On the other hand, the second option is to create in your application, the mechanism to ensure the new lists.

In my opinion, the best way for you to validate if some list was or wasn’t created into your SharePoint App, it is in Configuration/Settings View zone of your app because in this area, you can define app settings and validate if lists exist.  

To help you, I’ve created an extension based ListCollectionExtensions and the following code show you how you apply this:

using System.Linq;
using Microsoft.SharePoint.Client;
using System.Xml;

namespace Microsoft.SharePoint.Client
{
public static class ListCollectionExtensions
    {
        public static List EnsureList(this ListCollection lists, string listTitle, ListTemplateType listTemplateType) {
           return EnsureList(lists, listTitle, listTemplateType, new string[] { });
        }
        public static List EnsureList(this ListCollection lists, string listTitle, ListTemplateType listTemplateType, string[] schemaXmlField)
        {
            var ctx = lists.Context;
            var result = ctx.LoadQuery(lists.Where(l => l.Title == listTitle));
            ctx.ExecuteQuery();
            if (!result.Any())
            {
                var lci = new ListCreationInformation();
                lci.Title = listTitle;
                lci.TemplateType = (int)listTemplateType;
                var list = lists.Add(lci);
                ctx.Load(list);

                if (schemaXmlField.Length != 0)
                {
                    foreach (var str in schemaXmlField)
                    {
                        list.Fields.AddFieldAsXml(str,
                                        true,
                                        AddFieldOptions.DefaultValue);
                    }
                    ctx.ExecuteQuery();
                }

                
                return list;
            }
            else {
                List res = result.FirstOrDefault();
                ctx.Load(res, l => l.Fields);
                ctx.ExecuteQuery();

                if (schemaXmlField.Length != 0)
                {
                    foreach (var str in schemaXmlField)
                    {
                        XmlDocument xd = new XmlDocument();
                        xd.LoadXml(str);

                        var displayName = xd.DocumentElement.GetAttribute("DisplayName");

                        if (!res.Fields.Any(a => a.Title.Equals(displayName.ToString(), System.StringComparison.InvariantCultureIgnoreCase)))
                        {
                            res.Fields.AddFieldAsXml(str,
                                                true,
                                                AddFieldOptions.DefaultValue);

                        }
                        
                    }

                    ctx.ExecuteQuery();
                }
            }

            return result.FirstOrDefault();
        }
    }
}

This extension allows you to check if the list exist (if not, then creates the list)  and you have chance to add or not, more columns using string xml Field representation.

So now, I need just call the extension into your code.

 

List customList = ClientContextApp.Web.Lists.EnsureList(
   "CustomList", 
                 ListTemplateType.GenericList,
                 new string[] { "<Field DisplayName='IdentificationNumber' Type='Number'></Field>"); 

 

I hope you enjoy. See you later. bye 😊


0 Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.