SharePoint CSOM – Add a content type to a site and install an app

This is a small code snippet on how to add a content type to a site and how to install an app(or these days an Add-In). Notice that adding an app this way is not the recommended way. This is “cheating”, well the recommended way to add an app to a production environment is through a app catalog or a store BUT if you do need to add it for some reason through CSOM well this is the way. You could also apply the same technique to PowerShell:


private static void EnsureDeveloperFeature(ClientContext ctx)
 {
 var result = ctx.LoadQuery(ctx.Site.Features.Where(f => f.DefinitionId == DeveloperFeatureId));
 ctx.ExecuteQuery();
 if (result.Any()) return;
 var feature = ctx.Site.Features.Add(DeveloperFeatureId, true, FeatureDefinitionScope.None);
 ctx.ExecuteQuery();
 }

 private static void DeleteDeveloperFeature(ClientContext ctx)
 {
 var result = ctx.LoadQuery(ctx.Site.Features.Where(f => f.DefinitionId == DeveloperFeatureId));
 ctx.ExecuteQuery();
 if (!result.Any()) return;
 ctx.Site.Features.Remove(DeveloperFeatureId, true);
 ctx.ExecuteQuery();
 }

 private static void EnsureContentTypeAndRibbonApp(ClientContext ctxWorkspace, string administratorsEmail)
 {
 try
 {
 var contentTypeName = ConfigurationManager.AppSettings["ContentTypeName"].ToString();
 var appFullPath = ConfigurationManager.AppSettings["RibbonAppFullPath"].ToString();

 if (String.IsNullOrEmpty(contentTypeName) && String.IsNullOrEmpty(appFullPath))
 return;

 Web currentWeb = ctxWorkspace.Web;
 ctxWorkspace.Load(currentWeb);
 

 var webContentTypes = currentWeb.ContentTypes;
 ctxWorkspace.Load(webContentTypes);
 var apps = currentWeb.GetAppInstances();
 ctxWorkspace.Load(apps);
 ctxWorkspace.ExecuteQuery();

 // Install the ribbon achieving ribbon app if the app file exists and does not exist already
 if (System.IO.File.Exists(appFullPath) && apps.SingleOrDefault(o => o.Title.Contains(ConfigurationManager.AppSettings["ArchivingRibbonAppName"].ToString())) == null)
 {
 EnsureDeveloperFeature(ctxWorkspace);
 using (var packageStream = System.IO.File.OpenRead(appFullPath))
 {
 var appInstance = ctxWorkspace.Web.LoadAndInstallApp(packageStream);
 ctxWorkspace.Load(appInstance);
 ctxWorkspace.ExecuteQuery();
 if (appInstance != null && appInstance.Status == AppInstanceStatus.Initialized)
 {
 Console.WriteLine("App was installed on:" + currentWeb.Url);
 }
 }
 DeleteDeveloperFeature(ctxWorkspace);
 }
 
 



 var contentType = webContentTypes.SingleOrDefault(o => o.Name.Contains(contentTypeName));

 if(contentType != null)
 {
 ctxWorkspace.Load(contentType);
 ctxWorkspace.ExecuteQuery();

 ListCollection lists = ctxWorkspace.Web.Lists;
 var sourceWeb = ctxWorkspace.Web;
 ctxWorkspace.Load(sourceWeb);
 ctxWorkspace.Load(lists);
 ctxWorkspace.ExecuteQuery();

 foreach (List list in lists.Where(o => o.BaseType == BaseType.DocumentLibrary))
 {
 if (list.Hidden || list.IsApplicationList || list.IsCatalog)
 continue;
// Check for existing content types only if content type management is set to active
 if (list.ContentTypesEnabled)
 {
 var listCTs = list.ContentTypes;
 ctxWorkspace.Load(listCTs);
 ctxWorkspace.ExecuteQuery();
 if (listCTs.SingleOrDefault(o => o.Name == contentType.Name) != null)
 continue;
 }
 list.ContentTypesEnabled = true;
 list.Update();
 ctxWorkspace.ExecuteQuery();

 list.ContentTypes.AddExistingContentType(contentType);
 list.Update();
 ctxWorkspace.ExecuteQuery();
 }
 }

 
 }
 catch (Exception ex)
 {
 
 }
 }


Advertisements

O365 CSOM – Client Side Object Model examples

Here are some examples on how to use CSOM with O365:

This is Microsofts’ link on the matter for more examples:

https://msdn.microsoft.com/en-us/library/ff798388.aspx

 

Remove SiteCollection


 var tenantAdminUri = new Uri(tenantAdminUrl);
 string realm = TokenHelper.GetRealmFromTargetUrl(tenantAdminUri);
 var token = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, tenantAdminUri.Authority, realm).AccessToken;
 using (var tenantContext = TokenHelper.GetClientContextWithAccessToken(tenantAdminUri.ToString(), token))
 {
 // Set the time out as high as possible
 tenantContext.RequestTimeout = int.MaxValue;

 var tenant = new Tenant(tenantContext);

 //start the SPO operation to create the site
 SpoOperation op = tenant.RemoveSite(webUrl);
 tenantContext.Load(op, i => i.IsComplete);
 tenantContext.RequestTimeout = int.MaxValue;
 tenantContext.ExecuteQuery();

 while (!op.IsComplete)
 {
 Console.WriteLine("Waiting 30 seconds site to be provisioned");
 //wait 30seconds and try again
 System.Threading.Thread.Sleep(30000);
 op.RefreshLoad();
 tenantContext.ExecuteQuery();
 }
 }

 Updating a list item

</pre>
List list = ctx.Web.Lists.GetByTitle(ConfigurationManager.AppSettings["SiteCollectionRequests_List"]);
ListItem listItem = list.GetItemById(id);
ctx.Load(listItem);
ctx.ExecuteQuery();

statusMessage += "Your message";
listItem["StatusMessage"] = statusMessage;
listItem.Update();
list.Update();
ctx.Web.Update();
ctx.ExecuteQuery();
<pre>

Adding a new item to a list


List list = ctx.Web.Lists.GetByTitle(ConfigurationManager.AppSettings["SiteCollectionRequests_LogList"]);

 ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
 ListItem newItem = list.AddItem(itemCreateInfo);
 newItem["Title"] = title;
 newItem["url"] = workspaceURL;

 XmlSerializer xs = new XmlSerializer(typeof(WorkspacePrivileges));
 StringWriter sww = new StringWriter();
 XmlWriter writer = XmlWriter.Create(sww);
 xs.Serialize(writer, workspacePrivileges);
 String aaa = sww.ToString();

 newItem["my text field"] = sww.ToString();
 newItem.Update();
 ctx.ExecuteQuery();

Change Workspace Privileges To Read Only


Uri siteUrl = new Uri(workspaceURL);
 string realm = TokenHelper.GetRealmFromTargetUrl(siteUrl);
 var token = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUrl.Authority, realm).AccessToken;
 using (var ctxWorkspace = TokenHelper.GetClientContextWithAccessToken(siteUrl.ToString(), token))
 {
 Web currentWeb = ctxWorkspace.Web;
 ctxWorkspace.Load(currentWeb);

 UserCollection webUsers = currentWeb.SiteUsers;
 ctxWorkspace.Load(webUsers);
 ctxWorkspace.ExecuteQuery();
 List<String> usersToAddReadOnlyRights = new List<string>();

 foreach(User user in webUsers)
 {
 if (user.LoginName.ToLowerInvariant().Contains("membership"))
 {
 if (!user.IsSiteAdmin)
 {
 webUsers.RemoveById(user.Id);
 usersToAddReadOnlyRights.Add(user.LoginName);
 }
 }
 }
 currentWeb.Update();
 ctxWorkspace.ExecuteQuery();

 Group visitorGroup = ctxWorkspace.Web.SiteGroups.GetByName(ctxWorkspace.Web.Title + ConfigurationManager.AppSettings["WorkspaceVisitors"]);
 ctxWorkspace.Load(currentWeb);
 ctxWorkspace.Load(visitorGroup);
 ctxWorkspace.Load(webUsers);
 ctxWorkspace.ExecuteQuery();
 foreach (String user in usersToAddReadOnlyRights)
 {
 String[] userLoginNameArray = user.Split('|');
 if(userLoginNameArray != null && userLoginNameArray.Length > 1)
 {
 UserCreationInformation userInfo = new UserCreationInformation();
 userInfo.LoginName = userLoginNameArray[2];
 currentWeb.AddUserToGroup(visitorGroup, userLoginNameArray[2]);

 }
 }
 currentWeb.Update();
 ctxWorkspace.ExecuteQuery();

Remove Workspace users privileges And deny Search Indexing on lists


Uri siteUrl = new Uri(workspaceURL);
 string realm = TokenHelper.GetRealmFromTargetUrl(siteUrl);
 var token = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUrl.Authority, realm).AccessToken;
 using (var ctxWorkspace = TokenHelper.GetClientContextWithAccessToken(siteUrl.ToString(), token))
 {

 Web currentWeb = ctxWorkspace.Web;
 ctxWorkspace.Load(currentWeb);
 ListCollection lists = ctxWorkspace.Web.Lists;
 ctxWorkspace.Load(lists);
 UserCollection webUsers = currentWeb.SiteUsers;
 ctxWorkspace.Load(webUsers);
 ctxWorkspace.ExecuteQuery();

 foreach (List list in lists)
 {
 list.NoCrawl = true;
 list.Update();
 }

 foreach (User user in webUsers)
 {
 if (user.LoginName.ToLowerInvariant().Contains("membership"))
 {
 if (!user.IsSiteAdmin)
 {
 webUsers.RemoveById(user.Id);
 }
 }
 }
 currentWeb.Update();
 ctxWorkspace.ExecuteQuery();