I’ve been writing a client side object model script to set up some sites, including setting some the navigation settings on the site. Sadly, Microsoft have written SharePoint to involve at least 3 objects in the navigation settings for a site (PublishingWeb, WebNavigationSettings, and SPNavigation. At least. It’s totally effing bonkers.), and those objects don’t work in quite the same way for CSOM. For example, it’s not clear how to set a site to ‘show subsites’ in the global navigation. Continue reading “Set Global Nav in CSOM”
CSOM
Turn off the Minimum Download Strategy feature in CSOM
I have found that the Minimum Download Strategy can cause issues with some of the JavaScript/JQuery I used in some of my pages – particularly when using Display Templates. I’m not the only person to have problems with it, either. Well, here’s the CSOM to turn it off:
private static void RemoveMinimalDownload(ClientContext clientContext, Web web) { Guid MDSfeature = new Guid("87294C72-F260-42f3-A41B-981A2FFCE37A"); FeatureCollection features = web.Features; clientContext.Load(features); clientContext.ExecuteQuery(); features.Remove(MDSfeature, true); clientContext.ExecuteQuery(); }
Working with fields in CSOM
I’ve already detailed how to create a new Taxonomy Field in CSOM – here’s the more generic how to create a general field on a list.:
internal static void CreateFields(ClientContext clientContext, List targetList, string xmlDef) { targetList.Fields.AddFieldAsXml(xmlDef, true, AddFieldOptions.AddFieldInternalNameHint); clientContext.ExecuteQuery(); }
And as a bonus, here’s how to set a field to be indexed in the client side object model:
internal static void SetIndex(ClientContext clientContext, List list, string fieldName) { Field f = list.Fields.GetByInternalNameOrTitle(fieldName); clientContext.Load(f); clientContext.ExecuteQuery(); f.Indexed = true; f.Update(); list.Update(); clientContext.ExecuteQuery(); }
Upload a File with CSOM
This is an example of how to upload a file with the C# Client Side Object Model (CSOM):
internal static File UploadFile(ClientContext clientContext, Web web, string filePath, Folder folder, string fileName, string title) { string target = folder.ServerRelativeUrl + "/" + fileName; FileCreationInformation fci = new FileCreationInformation(); fci.Overwrite = true; fci.Url = target; fci.Content = System.IO.File.ReadAllBytes(filePath); File uploadedFile = folder.Files.Add(fci); uploadedFile.ListItemAllFields["Title"] = title; uploadedFile.ListItemAllFields.Update(); clientContext.ExecuteQuery(); if (uploadedFile.CheckOutType != CheckOutType.None) { uploadedFile.CheckIn("Initial Upload", CheckinType.MajorCheckIn); } clientContext.Load(uploadedFile); clientContext.ExecuteQuery(); return uploadedFile; }
Note that this method also lets you set a title for the document, as well as the file name, and it checks the document in for you if required.
What does TaxonomyItem.NormalizeName() do?
So, the client side application I’ve been working on has to sync a LOT of terms to the term store, and I’ve mentioned how I had problems with Managed Metadata labels and the ampersand – and how I fixed them using TaxonomyItem.NormalizeName().
Well, that was fine, but my application was slow – so I started looking at what I could do to eliminate client side object model calls (CSOM). My suspicion was that, as the function was static, it wasn’t doing anything that I couldn’t do in my application, and save a round trip to the server.
So, I opened up reflected and decompiled Microsoft.SharePoint.Taxonomy.dll. Inside I found the code for the following:
Regex _trimSpacesRegex = new Regex(@"s+", RegexOptions.Compiled | RegexOptions.IgnoreCase); //Normalize name as Taxonomy Service does string name = _trimSpacesRegex.Replace(termName, " ").Replace('&', 'uff06').Replace('"', 'uff02').Trim();
That’s much, much faster than a round trip to the server, and I learnt that speechmarks are also converted from ASCII to Unicode too.
Managed Metadata Labels and the Ampersand character
I am writing an application to import/generate a number of terms in a term set. I started to get some errors about my code trying to add terms that already exist – but it does check for the existence of terms with a given name.
You can see that the string comparison for the name of the existing term and the term I want to get/create returns false, and that the terms seem to be different lengths. Well, I tried looking for blank spaces, non-printing characters, carriage returns, etc., and found nothing. Then I looked really closely at the ampersand characters shown in the debugger:
Yup, they’re different characters. You can see a slightly different shape to each of them – one is wider. Continue reading “Managed Metadata Labels and the Ampersand character”
What happens with a large TaxonomyHiddenList?
SharePoint’s Taxonomy (or “Managed Metadata”) fields are a bit strange in how they work. In a lot of ways they’re actually like a lookup field, and part of this lookup field is that site collections that use them have a hidden list – called TaxonomyHiddenList – in the root of the site collection. You can find it at /lists/TaxonomyHiddenList/.
Each term that is used in a Taxonomy field has it’s label (actually, labels) and other details kind of ‘cached’ in this list, and there is a timer job that will push changes to the terms out into these lists – and therefore to items that refer to the entries in the list. Continue reading “What happens with a large TaxonomyHiddenList?”
Working with the Taxonomy in CSOM
Building on my previous post, once you’re connected to your SharePoint server, you might need to do a few things – like set up Term Groups and Sets in the Taxonomy service. You’ll need your application to reference the Microsoft.SharePoint.Client.Taxonomy assembly. Continue reading “Working with the Taxonomy in CSOM”
Connect to Office 365 with CSOM
If you’re going to connect to SharePoint Online 2013 in Office 365, you’ll need to reference a few assemblies in your solution:
- Microsoft.SharePoint.Client
- Microsoft.SharePoint.Client.Runtime
- System.Security
You’ll find these in the SharePoint Server 2013 Client Components SDK if you’ve not got them already.
In your code you’ll then need to create a ClientContext for your connection, including creating a SharePointOnlineCredentials object, and then you can start to talk to your SharePoint instance.
string url = "https://example.sharepoint.com/sites/testsite"; string username = "Office365User@example.com"; string userpass = "password"; using (ClientContext clientContext = new ClientContext(url)) { Console.WriteLine("Connecting to {0} as {1}", url, username); SecureString passWord = new SecureString(); foreach (char c in userpass.ToCharArray()) passWord.AppendChar(c); clientContext.Credentials = new SharePointOnlineCredentials(username, passWord); Web web = clientContext.Web; clientContext.Load(web); clientContext.ExecuteQuery(); Console.WriteLine("Got Web {0}", web.Url); }
And this will be the basis of my future examples of doing things in Office 365 SharePoint using CSOM.
Powershell in Office 365 … and why you need CSOM
Edit: It seems Chris O’Brien has been thinking about the same problem, and has a good post about it.
Microsoft claim that Office 365 has PowerShell support. I had assumed that this meant that most, or at least many, of the PowerShell commands I can use in a normal farm would also be available in Office 365.
I was wildly, spectacularly wrong. Continue reading “Powershell in Office 365 … and why you need CSOM”