SharePoint vs (?) ASP.NET MVC

I’ve been studying ASP.NET MVC 4 over the last while; this is the subject of second of the 4 exams required for the SharePoint Developer MCSD, and I really need to spend some time on that.

The idea of an MVC (Model-View-Controller) framework is to separate the different concerns of your code, and that usually this allows you to design a data model, and then let your tools create a scaffolding of your site. Such things aren’t new; I implemented a Chinese Chess web site in Ruby on Rails which uses this approach in 2005. I loved the MVC approach. Continue reading “SharePoint vs (?) ASP.NET MVC”

SharePoint vs (?) ASP.NET MVC

On the 70-488 – SharePoint Core Solutions Exam

No brain-dumps or anything here; if you want the answers, go and study. However, it’s worth knowing about the structure of the exam.

Right, so this is one of the 4 exams you’ll need for the MCSD SharePoint Applications. We decided to fling me at this one without preparation – I’m a SharePoint developer, so shouldn’t I be good at this one without lots of learning?

Continue reading “On the 70-488 – SharePoint Core Solutions Exam”

On the 70-488 – SharePoint Core Solutions Exam

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();
}
Turn off the Minimum Download Strategy feature in CSOM

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();
}
Working with fields in CSOM

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.

Upload a File with CSOM

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.

What does TaxonomyItem.NormalizeName() do?

Remote Event Receivers: Identify when a document's metadata is first completed

Document events are a perennial problem in SharePoint. This is, in part, due to the way documents are put into SharePoint:

  • You upload the document into SharePoint…
  • …which fires ItemAdded …
  • …then you complete the metadata…
  • …which fires item updated.

So, my problem was that our customer wanted an email sent when a document was first ‘added’ to SharePoint – except that by added they meant “Has been uploaded and it’s metadata completed for the first time”. While SharePoint does, technically, fire the correct events at the correct times, it’s pretty easy to see this ‘business event’ is probably more useful. Continue reading “Remote Event Receivers: Identify when a document's metadata is first completed”

Remote Event Receivers: Identify when a document's metadata is first completed

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.My Code and existence check

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:

Strings 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”

Managed Metadata Labels and the Ampersand character

Timed Jobs in Azure Provider-Hosted Apps

As I’ve described recently, I’m working on a Provider-Hosted SharePoint App that’s hosted in Azure. I’ve said previously about using Remote Event Receivers, and this whole app is really about sending emails from SharePoint Online (which we’re doing via SendGrid).

One of the things the customer wants is ‘timed’ emails – that is, some sort of service that talks to SharePoint Online, checks to see if there are any items in a list that are due for action, and if so sends an alert email. Simple enough, but with one minor problem. There are no timer jobs in SharePoint Apps. And you can’t put them into Office 365. And Azure doesn’t have an equivalent … yet. Continue reading “Timed Jobs in Azure Provider-Hosted Apps”

Timed Jobs in Azure Provider-Hosted Apps

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/.

Hidden

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?”

What happens with a large TaxonomyHiddenList?