How to set O365 PageLayout Associated Content Type field

Here is a code snippet to set your page layouts associated content type. This one was a bit weird when I first tried to set it.

 private static void SetPageLayoutMetadata(Web web, File uploadFile, string title, string publishingAssociatedContentType)
{
// Speficy that the page layout is a page layout and not a master page
var parentContentTypeId = ""0x01010007FF3E057FA8AB4AA42FCB67B453FFC100E214EEE741181F4E9F7ACC43278EE811""; //Page Layout
var gallery = web.GetCatalog(116);
web.Context.Load(gallery, g => g.ContentTypes);
web.Context.ExecuteQuery();

var contentTypeId = gallery.ContentTypes.FirstOrDefault(ct => ct.StringId.StartsWith(parentContentTypeId)).StringId;
var item = uploadFile.ListItemAllFields;
web.Context.Load(item);

item["ContentTypeId"] = contentTypeId;
item["Title"] = title;
item["PublishingAssociatedContentType"] = publishingAssociatedContentType;

item.Update();
web.Context.ExecuteQuery();
} 

Two important things:

  • parentContentTypeId: This is the ID that tells O365 that this page layout is actually page layout, this is a static id which is defined in the code
  • publishingAssociatedContentType: This is your actual content type to which you want to associate your page layout to: Example of the format:;#my content type name;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D00A3428808D7DE6A4RABF83921AFB25424;#
    • So the format should be in the following way:

public static String BuildPublishingAssociativeContentTypeId(ContentType contentType)
{
String contentTypeAssociativeID = null;
if(contentType != null)
{
contentTypeAssociativeID = String.Format(";#{0};#{1};#", contentType.Name, contentType.StringId);
}

return contentTypeAssociativeID;
}

Advertisements

O365 OfficeDev PnP CSOM tools installation

This post will assume you have Visual Studio installed with Microsoft Office 365 API tools for Visual Studio.

  • Create a new Visual Studio project, lets say a console application.
  • Press on your project the second mouse button and select “Manage NuGet Packages…”
  • In the new window search for online packages and type in pnp or officedevpnpcore or similar. Then install the OfficeDevPnp.Core.Online package.

OfficePnp1

  • Wait for the installation to complete. After this you are ready to use CSOM to operate on your desired O365 site.

OfficePnp2

As you can see from the image above the nuget package will install all of what you need. You do not have to worry about much. Easy, right :)?

Links to know:

https://github.com/OfficeDev/PnP

https://channel9.msdn.com/blogs/OfficeDevPnP/Getting-Started-with-PnP-Provisioning-Engine

https://github.com/OfficeDev/PnP-Partner-Pack

http://dev.office.com/patterns-and-practices-resources

http://dev.office.com/blogs/new-sharepoint-csom-version-released-for-Office-365

https://www.nuget.org/packages/Microsoft.SharePointOnline.CSOM

https://lionadi.wordpress.com/2015/06/22/office-365-o365-client-application-registration-authentication-and-authorization/

https://lionadi.wordpress.com/2015/07/02/o365-csom-client-side-object-model-examples/

https://lionadi.wordpress.com/2015/09/16/o365-csom-getting-user-profile-information-without-possible-errors/

https://lionadi.wordpress.com/tag/o365/

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();

Office 365( O365 ) – Client application registration, authentication and authorization

OK,

I am currently working on a client side application (console app) that needs to connect to a O365 site and do some stuff with CSOM.

In this post I will write some basic things you need to do in order to achieve a connection to an O365 site. In my case I am working with a console app but this can be a powershell app also.

At first I recommend you look at this piece of code which you need to use to achieve the communication and authentication with O365:

https://github.com/OfficeDev/SharePoint-Power-Hour-Code-Samples/blob/master/SP.SiteCreatorWeb/TokenHelper.cs

https://github.com/OfficeDev/SharePoint-Power-Hour-Code-Samples

A basic C# code to connecto O365 and do get a list and its items would look like this:


Uri siteUri = new Uri(ConfigurationManager.AppSettings["SiteCollectionRequests_SiteUrl"]);

 //Get the realm for the URL
 string realm = TokenHelper.GetRealmFromTargetUrl(siteUri);

 //Get the access token for the URL.
 //Requires this app to be registered with the tenant
 string accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUri.Authority, realm).AccessToken;

 //Get client context with access token
 using (var ctx = TokenHelper.GetClientContextWithAccessToken(siteUri.ToString(), accessToken))
 {

 // Set the time out as high as possible
 ctx.RequestTimeout = int.MaxValue;

 List list = ctx.Web.Lists.GetByTitle(ConfigurationManager.AppSettings["SiteCollectionRequests_List"]);
 CamlQuery camlQuery = new CamlQuery();
 camlQuery.ViewXml = "your CAML query here";
 ListItemCollection listItems = list.GetItems(camlQuery);
 ctx.Load(listItems);
 ctx.ExecuteQuery();

 var itemsCount = listItems.Count;

So before you can use your code you need to do two things in your target site:

  1. Register you client side app. This basically means that in your app config you need to set a clientID and a client secret. Without these values no proper authentication and authorization can done.
    1. Register you app in O365 by using the following URL and replacing the hostname and adding your target site: http://<SharePointWebsite>/_layouts/15/AppRegNew.aspx
  2. After you register the app you need to need to specify in a target site what kind of privileges the app has. In the code sample above you would need to specify at least read rights.
    1. To provide privileges the following url: http://<SharePointWebsite>/_layouts/15/AppInv.aspx
    2. Notice that for this step you need to provide a XML describing the privileges request. The simples way for me was to start up Visual Studio, create an app and define the rights request through the GUI and copy & pasting the XML from the AppMenifest.xml. It would look something like this:
      1. <AppPermissionRequests AllowAppOnlyPolicy=”true”>
        <AppPermissionRequest Scope=”http://sharepoint/content/sitecollection/web/list&#8221; Right=”FullControl” />
        </AppPermissionRequests>

Also the last thing which you need to check is to have a proper configurations in the app.config(if you are using an console app):


<appSettings>
 <add key="ClientId" value="client id obtained after registration" />
 <add key="ClientSecret" value="client secrect after registration" />
 <add key="SiteCollectionRequests_SiteUrl" value="yoursiteurl"/>
 <add key="SiteCollectionRequests_List" value="listname" />

 </appSettings>

Also notice that the ClientId and the ClientSecret have to be provided in the app.config for the TokenHelper.cs class to work. The class will search for these settings values automatically.

Additional help here: http://blog.vgrem.com/2015/01/27/consuming-the-sharepoint-online-rest-api-from-powershell-part-2/

https://msdn.microsoft.com/en-US/library/fp142383.aspx

https://msdn.microsoft.com/library/fp179892(office.15).aspx

https://msdn.microsoft.com/en-us/library/office/fp179912.aspx#BasicOps_SPListItemTasks