Friday, 19 April 2013

SharePoint Client Object Model

I have been doing a lot of work with the SharePoint Client Object Model (COM) and wanted to share some of my experiences.  The COM is going to be more important as we start building more mobile applications and think about building SharePoint apps.

First off, I did not start with the SharePoint COM; I thought I would be able to build my site using the SharePoint REST web services.  One of my requirements though was to be able to use Anonymous access and that just doesn’t seem to be possible with the REST web services in 2010.  Although, if anybody knows how to do this, I would love to know.  So I ended up with the COM as it supports both authenticated and anonymous users (assuming of course that your Site Collection has been properly setup to allow anonymous users).  Overall the COM and REST web services do pretty much the same thing, although the COM does have this neat feature of being able to put together multiple actions into a single request.  All and all I may have been forced into the correct method after all.

The basic usage of the COM is very similar to the Object Model.  For example here is the code to get all the list items from a list:
using (ClientContext sharePoint = new ClientContext(_strSPURL))

                Web web = sharePoint.Web;
                ListCollection spLists = web.Lists;
                List spList = spLists.GetByTitle("Pages");
                CamlQuery camlQuery = new CamlQuery();

                camlQuery.ViewXml = @"<View>
                                        <FieldRef Name='ID'/>
                                        <FieldRef Name='AudienceTaxHTField0' />
                                        <FieldRef Name='ServiceTaxHTField0' />
                                        <FieldRef Name='Title' />
                                        <FieldRef Name='ContentTypeId' />
                                            <FieldRef Name='Modified' Ascending='False'/>

                Microsoft.SharePoint.Client.ListItemCollection spListItems = spList.GetItems(camlQuery);

                sharePoint.Load(spListItems, items => items.Include(
                                                        item => item["ID"],
                                                        item => item["AudienceTaxHTField0"],
                                                        item => item["ServiceTaxHTField0"],
                                                        item => item["Title"],
                                                        item => item["ContentTypeId"]));


                return spListItems;


As you can see, it is pretty much the same as you do now.  The ClientContext is like opening a SPSite object.  After that we open a SPWeb object, get the list, run a CAML query and return the items.  The other thing you may notice is that I explicitly tell SharePoint which fields to return.  This ensures SharePoint only returns the data I’m interested, the smallest package possible; as a side note you should also be doing this when using the Object Model…I mean have you seen all the crap SharePoint returns if you don’t do this?

Some gotcha’s
You can only use this against a Site Collection.  You have no access to anything higher.

The biggest gotchas I ran into where with the Taxonomy fields.  In the 2010 COM there are no Taxonomy Field objects (they are in the 2013 COM).  This means when trying to get data from Taxonomy fields you will have to reference the hidden Taxonomy field that is associated to the field you are interested.  You’ll noticed in the above example I’m referencing AudienceTaxHTField0 and not Audience which is the field you would see when using the site.  The other piece is the value coming back from this field will be the raw form, meaning that you will need to massage it a bit for it to be useful, unless of course you love GUIDs.

The other thing to keep in mind is performance.  Since your application will be making web service calls to SharePoint, using the COM, each request will have a minimum round trip time.  When coding try to limit the amount of round trips as much as possible and if possible think of using asynchronous methods so that the page doesn’t have to wait for all the data before it starts rendering.  Remember, it will be quicker to get a bunch of data and massage it in your app/site rather then make several little calls…to a point as if you ask for too much data this will also have a negative impact on the round trip time…you’ll need to find a balance.


SharePoint Project Planning

Congratulate yourself for actually accepting planning is required with SharePoint.  I know Microsoft likes to tell us you can just turn it on and use it, but we all know that’s just not the case.  Too many places are stuck with the pilot that never ends.  Starting with pilot or POC is great approach, but for it to work you need to circle back and actually plan a proper deployment that includes DR, Availability and Performance.  The Pilot that never dies had none of these consideration and is like a ticking time bomb, who will be the first user that picks up the phone to complain the site is unusable?  Will it be the CEO?  More importantly will you be able to fix it?

To begin with make sure you have the correct people for the job.  If you are going to train up internal resources to do the job, ensure the training happens early, ideally before any solution planning.  This is because the team planning the SharePoint solution will need to lead the end users to the solution.  It's hard for the end user to ask for what they want, when they don't know what is available.  Ask any SharePoint professional and there are many tools, tips and quirks to using SharePoint that only someone with experience would think of.  If no one knows how SharePoint works, it becomes the blind leading the blind.  Which is why, even if you are planning to train up your internal resources, you should ensure you have an experienced SharePoint professional on the project.  As we all know, there are something's that only experience can teach us.

Once you have armed your team with this knowledge, the end users are going to ask for things that are known limitations of SharePoint.  While it is always a great strategy to use OOTB functionality, don't be too rigid on this.  Rather than just saying no, or agreeing to a complex custom solution, be prepared with work arounds or alternatives that may speak more to the spirit of the request.  After all, if the site is usable to the end user, who is going to use it.  But if it's overly customized who is going to support it?

Now that you have enough information to design a solution that will meet the end users' needs don’t' forget to consider the following in your design: High Availability, Disaster Recovery, Automated deployment to the multiple environments (UAT, Staging, Production), Security, Internal vs. External access, mobile (becoming bigger by the day), performance and of course monitoring. 

Be agile in development, especially with people that don't have much SharePoint exposure or experience.  Again, when people don't know SharePoint, they can't know what to ask for.  By giving the users prototypes or sneak previews into the solution you can identify gaps early and have a much better chance of delivering a solution the end user will actually use.

Test, test and test; be sure testers also have SharePoint training.  Otherwise how will they know what to test and how to test OOTB features?  During this testing be sure to test in an environment that simulates production.  If you're going to have a highly available environment with multiple Web Front End Servers, or you're using SSL, be sure to test these conditions.  I've seen many issues arise from these that are not reproducible in a single WFE, non SSL setup.  In addition ensure you test your nonfunctional features like Performance, High Availability, Disaster Recovery and monitoring.  After all if you don't test them, you don’t' have them.

Now that you have it in Production, the job isn't over.  We've simply moved to the next step in the SharePoint lifecycle: Build, monitor, review and improve.  After all the end users job is always evolving, your site will need to keep up.