Deep dive into the SharePoint 2013 CSOM API's

Preview:

Citation preview

Deep dive into the SharePoint 2013 CSOM API'sTravis FallsSr. ConsultantMicrosoft Services

SPC407

Steve WalkerSr. Program ManagerMicrosoft – Office365

CAT

Office 365 Platform Contextual Apps

Robust O365 API’s Flexible Tools Documents People | Groups

Mail Tasks

Calendars REST Web Services

Developer Renaissance

IISASP.NET

SharePoint

(your app)

IISASP.NET

SharePoint

IISIISASP.NET

(your app)

CSOM & REST

Events

IISASP.NET

Shar

ePoi

nt

(you

r app

)

CSOM

& R

EST

Requires deep understanding of SharePoint UI/Server OM

Shared process space & page pipeline – Efficient but risky

Protocols drive a “wedge” in monolithic development

Decouple SharePoint idioms from application logic

Return to more traditional development

UI aggregates at the client, not the server

SharePoint Client Protocols

IPTCP

HTTPJSON [RFC4627] / ATOM + XML

MS-CSOMSPTMS-CSOMREST

MS-ODATA

API’s (Client.x, SP.x, HttpRequest, $.ajax)

Browser Windows ASP.NET WorkflowsEvent

Receivers

[7] Application

[4] Transport[3] Network

Industry

Standard

OSIModel

MicrosoftOpen

Specification

MS-CSOM

MS-SRCHCSOMMS-SOCCSOMMS-EMMCSOM

MS-COMMCSOMMS-PUBCSOMMS-DMCSOMMS-EDCSOM

JavaScript Library

Silverlight Library

.NET CLR Library

ClientCode

ClientServer

SharePoint 2013 Remote API

RESToDat

aJSON CSOM

_api (_vti_bin/client.svc)

Sharing SocialTaxonom

y Search

Publishing

eDiscovery

_api is all you need in 2013• In SharePoint 2010, We had CSOM • In SharePoint 2010, we had REST• http://localhost/_vti_bin/listdata.svc/Parts• All we had was listdata.svc – good for list operations only

• SharePoint 2013 consolidated them into _api• Massively expanded the restful-ness of SharePoint• Not only lists this release. Sites, Webs, collections • More advanced query capabilites

How does _api map to _vti_bin\client.svc?

public sealed class SPRequestModule : IHttpModule{ public void BeginRequestHandler(object oSender, EventArgs ea) { // Illustration, not actual code. if (RequestPathIndex == PathIndex._api) { string clientSvc = "/_vti_bin/client.svc/"; int apiStart = requestVirtualPath.IndexOf("/_api/", StringComparison.OrdinalIgnoreCase); if (apiStart >= 0) { clientSvc = clientSvc + filePath.Substring(apiStart + "/_api/".Length); } RequestPathIndex = PathIndex._vti_bin; } }}

How does client.svc handle both REST and CSOM?

[ServiceContract(Namespace= "http://schemas.microsoft.com/sharepoint/soap/")]public interface IClientRequestService{ // Illustration, not actual code. [WebInvoke(Method= "POST", UriTemplate= "ProcessQuery"), OperationContract] Stream ProcessQuery(Stream inputStream);

[WebInvoke(Method= "*", UriTemplate= "*"), OperationContract] Stream ProcessRestQuery(Stream inputStream);}

CSOM (MS-CSOM)

What’s nice about CSOM? Structured, strongly typed, pragmatic,

abstracted Hierarchical and “stateful” Familiar for those used to the server object

model Efficient & concise in operation and syntax

(ex: LINQ, CAML, batching) Much easier to do TDD against CSOM as

opposed to REST Highly documented (MSDN, Intelli-sense,

object browser)

ClientContext – root of local cache, brokers communication to server, disposable

ClientObject – cache of transient data, translated to xml on request, de-serialized from JSon on responseex: Site, KeywordQuery, SearchExecutor

SecurableObject – derives from ClientObject and adds authorization semanticsex: Web, List, ListItem

ClientValueObject – similar to ClientObject for simple data types (string, integer)

ClientObjectCollection<T> - augments ClientObject with queryable and enumerable supportex: ListCollection, ListItemCollection, FieldCollection

ClientResult<T> - result of a method invocationex: GetFeedFor( ), SearchExecutor.ExecuteQuery( )

CSOM Foundational Objects

context.Load(…)context.LoadQuery(…)new SearchExecutor(context) context.load(…)

context.ExecuteQuery( )context.executeQueryAsync( )

string t = web.Titleforeach (ListItem item in oItems) { }var t = web.get_title( )

new ClientContext(url)TokenHelper.GetClientContext…( )SP.ClientContext.get_current( )

CSOM semanticsBuild

Request

Execute

Query

Process

Results

Create

Context

Create Context Top-level object of an interlinked

hierarchy Serialize, transmit, receive, deserialize Establishes the authentication approach Acquiring a context

SP.ClientContext.get_current( ) new ClientContext(url)

new ClientContext(url)SharePointContextProvider.GetSharePointContext( )SP.ClientContext.get_current( )

SharePointContextProvider

TokenHelper

NEW!

low trust high trust

Build Request Create/initialize client objects Load objects/actions into context

Load( ) – in-place load, returns data in the object itselfNote: some objects are implicitly loaded by constructor( )

LoadQuery( ) – queryable load, returns data in another result array, no affect on object state

LINQ to Objects (not LINQ to SharePoint) Query syntax (only LoadQuery) – from x in y where x.cow == “moo”

select x; Method syntax (Load or LoadQuery) – y.where(x => x.cow == “moo”);

Use CAML to query lists, instead of LINQ

context.Load(…)context.LoadQuery(…)new SearchExecutor(context) context.load(…)

Execute Query First and only time request is

exchanged with server Context object orchestrates round-trip

Serialize objects and actions into XML Request for Forms Digest (POST _vti_bin/sites.asmx, more info) Request for ProcessQuery as XML (POST

_vti_bin/client.svc/ProcessQuery) Receives response objects as JSON Deserializes JSON into objects

Synchronous or asynchronous options

context.ExecuteQuery( )context.executeQueryAsync( )

Process Results Moving data in/out of

in-memory objects No significant performance concerns May encounter “___NotInitializedException”

– missing a Load( ) directive LINQ to Objects could still be performed

here

string t = web.Titleforeach (ListItem item in oItems) { }var t = web.get_title( )

CSOM – Sites (Web, List, Item, doc-sets)using Microsoft.SharePoint.Client;

ClientContext context = new ClientContext("http://site");List oList = context.Web.Lists.GetByTitle("Announcements");CamlQuery camlQuery = new CamlQuery();camlQuery.ViewXml = "<View><Query><Where><Contains><FieldRef Name='Body'/>" + "<Value Type='Text'>TACOCAT</Value></Contains></Where></Query>" + "<RowLimit>10</RowLimit></View>“;ListItemCollection oItems = oList.GetItems(camlQuery);context.Load(oItems);context.ExecuteQuery();foreach (ListItem oListItem in oItems){

Console.WriteLine("ID: {0} \nTitle: {1} \nBody: {2}", oListItem.Id, oListItem["Title"], oListItem["Body"]);

}

MS-CSOMSPT – http://msdn.microsoft.com/en-us/library/dd958478.aspxMS-DMCSOM– http://msdn.microsoft.com/en-us/library/hh645775.aspx

CSOM – Search (keyword query)using Microsoft.SharePoint.Client.Search.Query;

ClientContext context = new ClientContext("http://site");KeywordQuery query = new KeywordQuery(context);query.QueryText = "ContentTypeId:0x0104*";query.SelectProperties.Add("Title");query.SelectProperties.Add("ContentTypeId");SearchExecutor executor = new SearchExecutor(context);ClientResult<ResultTableCollection> results = executor.ExecuteQuery(query);context.ExecuteQuery();foreach (var result in results.Value[0].ResultRows){

Console.WriteLine(string.Format("Result: Title={0} ({1})", result["Title"], result["ContentTypeId"]));}

MS-SRCHCSOM – http://msdn.microsoft.com/en-us/library/hh659202.aspx

search query web service deprecated

CSOM – Social (users, feeds, likes, follows)using Microsoft.SharePoint.Client.Social; using Microsoft.SharePoint.Client.UserProfiles;

SocialFeedManager fm = new SocialFeedManager(context);SocialFeedOptions options = new SocialFeedOptions()

{ SortOrder = SocialFeedSortOrder.ByCreatedTime };ClientResult<SocialFeed> feedResult = fm.GetFeed(SocialFeedType.News, options);context.ExecuteQuery();SocialFeed feed = feedResult.Value;foreach (SocialThread thread in feed.Threads){

SocialActor actor = thread.Actors[0];SocialPost post = thread.RootPost;Console.WriteLine(string.Format("{0} posted {1}", actor.Name,

post.Text));}

MS-SOCCSOM – http://msdn.microsoft.com/en-us/library/jj195162.aspxMS-COMMCSOM – http://msdn.microsoft.com/en-us/library/hh630219.aspx

CSOM – Taxonomy (Terms, Navigation)using Microsoft.SharePoint.Client.Taxonomy;

TaxonomySession session = TaxonomySession.GetTaxonomySession(context);TermStore store = session.GetDefaultSiteCollectionTermStore();TermSetCollection tsc = store.GetTermSetsByName("Colors", 1033);context.Load(tsc, list => list.Include(set => set.Terms));context.ExecuteQuery();TermSet colors = tsc[0];foreach (Term color in colors.Terms){

Console.WriteLine(color.Name);}

MS-MS-EMMCSOM – http://msdn.microsoft.com/en-us/library/hh661166.aspx

Optimizing Requests with LINQ// Larger response, filter at clientListCollection lists = context.Web.Lists;context.Load(lists);context.ExecuteQuery();foreach (List list in lists){ if (list.Hidden == true) { Console.WriteLine(list.Title); }}

// Smaller response, filter on servervar query = from list in context.Web.Lists where list.Hidden == true select list;var lists = context.LoadQuery(query);context.ExecuteQuery();foreach (List list in lists){ Console.WriteLine(list.Title);}

Batching Request

Sample Request Request contain

Actions (behavior) ObjectPaths (data)

Actions link to Object Paths

Objects form hierarchies with ParentId’s

Typical Actions ObjectPath – instantiates an object Query – gets scalar values for objects/types Set[Static]Property – assigns object property

Typical ObjectPaths StaticProperty – static object property Property – property of other object Method – results of a method call

Sample Respons

eObject Id’s align with request Id’s

Protocol defines standard envelope metadata

ex: _ObjectType_

Other properties carries data

Client AssembliesMicrosoft.SharePoint… Namespace…Client.Runtime.dll Microsoft.SharePoint.Client (client runtime context, web request)

...Client.dll Microsoft.SharePoint.Client (ClientContext, Site, Web, List, ListItem, User, RoleDefinition/Assignment)Microsoft.BusinessData.* (entities, lob systems, views, fields)Microsoft.SharePoint.Client.EventReceivers (SPRemoteEventType/Properties/Result)Microsoft.SharePoint.ApplicationPages.ClientPickerQuery (ClientPeoplePickerWebServiceInterface)Microsoft.SharePoint.Client.WebParts (LimitedWebPartManager, WebPart, WebPartDefinition)Microsoft.SharePoint.Client.Analytics (logging analytics events)

...Client.DocumentManagement

.dllMicrosoft.SharePoint.Client.DocumentSet (DocumentSet)Microsoft.SharePoint.Client.Video (VideoSet)

...Client.Publishing.dll Microsoft.SharePoint.Client.Publishing (PublishingSite/Web/Page, Variations)Microsoft.SharePoint.Client.Publishing.Navigation (TaxonomyNavigation, NavigationTerm/TermSet)

...Client.Search.dll Microsoft.SharePoint.Client.Search.Query (KeywordQuery, SearchExecutor)

...Client.Taxonomy.dll Microsoft.SharePoint.Client.Taxonomy (TaxonomySession, TermStore/Group/Set, Term)

...Client.UserProfiles.dll Microsoft.SharePoint.Client.UserProfiles (ProfileLoader, UserProfile, following)Microsoft.SharePoint.Client.Social (SocialFeed/Post/Thread/Actor)Microsoft.SharePoint.Client.Microfeed (MicroFeedManager/Store/Post/Thread)

Demo

Site Enumeration Demo – Stand Alone Application

JSOM

Differences between C# and JavaScriptC# JavaScriptusing Microsoft.SharePoint.Client; ExecuteOrDelayUntilScriptLoaded(initFunc,

“sp.js”); …or…$(document).ready(initFunc);

using (ClientContext context = new ClientContext(absoluteUrl))using (ClientContext context = TokenHelper…( ))

var context = SP.ClientContext.get_current();var context = new SP.ClientContext(relativeUrl);

string title = web.Title; var title = web.get_title();

context.Load(oList, list=>list.Title, list=>list.Created);

context.load(oList, ‘Title’, ‘Id’);context.load(oListColl, ‘Include(Title, Id)’);

context.ExecuteQuery();context.ExecuteQueryAsync();

context.executeQueryAsync(onSuccess, onError);

Value types: StringCollection Value types: string[], NaN

Automatic FormDigest handling Manual FormDigest handling

Issues creating RoleDefinitionBindingCollection’s

JavaScript NamespacesIncludeNamespace

NamespaceObjects

SP.js SP, SP.Sharing, SP.BusiessData, SP.SiteHealth, SP.UI, SP.Utilities, SP.WorkflowClientContext, Site, Web, List

SP.Publishing.js SP.Publishing, SP.Navigation

SP.Search.js Microsoft.SharePoint.Client.Search.QueryKeywordQuery, SearchExecutor

SP.Social.js SP.Social

SP.Taxonomy.js SP.Taxonomy

SP.UserProfiles.js SP.UserProfiles

Demo(s) Hybrid - Provider Hosted People Picker Demo (Using JSOM & CSOM approaches together)

Hybrid – Provider hosted app to create sub-sites(Using JSOM & CSOM approaches together)

http://officeams.codeplex.com

Source for great reference app implementationsPublishing channel for ready to use examples on apps,

which you can use in your own projects

Related SessionsTuesdaySPC402 – Develop Advanced Search-Driven SharePoint 2013 Apps (1:45pm, Palazzo I, J)SPC417 – Speed up your app development skills with API abstraction (5pm, Palazzo A-H)

WednesdaySPC373 – Building SharePoint solutions for mobile devices (10:45am, Palazzo I,J)SPC365 – Governing & configuring divisional sites in an enterprise environment (3:15pm, San Polo 3401-3503)SPC323 – SharePoint App best practices using OData and the SharePoint REST API (5pm, Palazzo A-H)

ThursdaySPC403 – Site provisioning techniques with SharePoint apps (9am, Palazzo K,L)SPC408 – SharePoint 2013 Apps with AngularJS (9am, Palazzo A-H)SPC409 – Deep dive: SharePoint and Office App Security Model (OAuth & S2S) (10:30am, Palazzo A-H)SPC423 – Deep dive: REST and CSOM comparison (10:30am, Palazzo I,J)

Explore our new Preview APIs

In-depth articles on MSDNSubject to change; not for production use

Connect with the community

Speak your mind at OfficeSPDev.UserVoice.ComSolve your roadblocks on StackOverflow

[Office] and [SharePoint]

Build using our toolsUnleash your development skills with Office Dev Tools for Visual Studio 2013 and Office 365 API Tools for Visual Studio 2013

Calls to Action

© 2014 Microsoft Corporation. All rights reserved. Microsoft, Windows, and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.