best practices
SharePoint Client object models provide an object-oriented system for
interoperating with SharePoint data from a remote computer or from
the browser. They use underlying SharePoint web services to interact
with SharePoint objects. SharePoint Client OM has provided access to
a subset of the types and members of the SharePoint server-side
object model which provides ability to perform most of the common
scenarios.
SharePoint Client object model (Javascript & Managed client OM) is a great way to communite with SharePoint data from outside of SharePoint but need to understand some of the limitations of the client OM.
When you host
the application that uses the CSOM outside the SharePoint server
(web application outside SharePoint server which uses SharePoint
Client OM) , then user credentials cannot be used until we use
constraint delegation. It uses only the application pool identity of
the web application because of double hop issue and not the actual
user credentials.
Update
SharePoint list items using client OM from other web app outside
SharePoint
It
updates the modified information of the items with the App pool
account and special handling is required to update the modified
information with the actual logged in user
User
userInfo =
site.RootWeb.EnsureUser(HttpContext.Request.LogonUserIdentity.Name);
//
Update Modified by Information
fileitem["Editor"]
= userInfo;
fileitem.Update();
Access
SharePoint using client OM from other web app outside SharePoint
The
SharePoint in build security cannot be used and only app pool
identity is being used to verify the access against SharePoint
objects. Client object model doesn’t support to check the
permission of the list item for the current user before updating the
same.
Server
side code
DoesUserHavePermissions(SPBasePermissions)
method is available in the following objects to verify the user’s
permission
public
bool
DoesUserHavePermissions(
SPUser
user,
SPBasePermissions
permissionMask
)
It also has overrides to pass the SPUser to get the permission for
that user. Managed client OM doesn’t have that.
Client
OM code
In
client OM Microsoft.SharePoint.Client
, the DoesUserHavePermissions method is available only at
the Web level and not at the ListItem & List level.
Custom code required to check the permissions for the user.
Below
code checks the permission for the APP POOL account in case of web
application hosted in a different server and not the current Logged
in user.
private
static
bool
DoesUserHasPermission(ClientContext
context, ListItem
listItem, PermissionKind
permKind)
{
//
Load the permissions before checking
context.Load(listItem,
t => t.EffectiveBasePermissions);
context.ExecuteQuery();
return
listItem.EffectiveBasePermissions.Has(permKind);
}
SPUtility.CreateISO8601DateTimeFromSystemDateTime
(); equivalent in SharePoint Client Object Model (CSOM). This is
being used in CAML query and need to filter some data fetched from
list based on Date.
Server
side code:
string
dateString =
Microsoft.SharePoint.Utilities.SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now);
Client OM:
Format the
string using string formatter
string
dateString = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ");
Performance
issue
In
the below code, targetListItem.File needs to be executed to
read a property. This needs to be done to all items in the
collection.
ListItemCollection
collPageListItem = pagesList.GetItems(camlQuery);
//
Load the List item collection and execute
clientContext.Load(collPageListItem);
clientContext.ExecuteQuery();
foreach
(ListItem
targetListItem in
collPageListItem)
{
//
TO Read the file Property server relative URL, NEED TO excute
targetListItem.File Object
clientContext.Load(targetListItem.File);
clientContext.ExecuteQuery();
SpPagesMetadata
pagesItem = new
SpPagesMetadata();
pagesItem.PageId
= targetListItem.Id;
//
TO Read the file Property server relative URL, NEED TO execute
targetListItem.File Object
pagesItem.PageUrl
= targetListItem.File.ServerRelativeUrl;
}
Optimized
approach,
Load
all the required values in the context and ExecuteQuery once
which reduces round trips to the server
//
Load the item and it's file at one time
clientContext.Load(collPageListItem);
clientContext.Load(collPageListItem,
items => items.Include(item =>item.File.ServerRelativeUrl));
clientContext.ExecuteQuery();
Load
only the required values E.g In the above code, we use only the
ServerRelativeUrl property from the file object and hence load that
alone.
Differences
in SPWeb and Web objects
SPWeb object has
some differences to get the SPweb context. In server side code, we
can create the instance of SPWeb without passing the exact web url.
Server
side code:
SPWeb
spWeb = spSite.OpenWeb(”/staffing/Pages/default.aspx”,
false)
Second boolean
value that specifies whether the exact URL must be supplied. If it’s
false, it will handle itself.
Client OM
code:
Microsoft.SharePoint.Client.Web
web = site.OpenWeb(”/staffing”);
Need to provide
only the web site relative url. No second parameter to handle the
above case.
SPSiteDataQuery
Not available with client OM
Unlike
the server side code, Site data query is not available in the Client
OM and hence search SharePoint across multiple sub sites with a
single query is not possible. Need to loop thru each sub site to
perform search.
SPRoleAssignmentCollection
To
remove all role assignment i.e. to remove a permission from an list
item in SharePoint is straight forward with server side code and
whereas in client managed object model, it’s little different.
Also, we can’t remove the permission without
knowing the SharePoint group or user.
Server
code
SPSecurity.RunWithElevatedPrivileges(delegate()
{
listItem.BreakRoleInheritance(true);
while
(listItem.RoleAssignments.Count > 1)
{
listItem.RoleAssignments.Remove(0);
// Index
listItem.RoleAssignments.RemoveById(0);
// based on ID
}
});
Client OM
code
To remove the
role Assignment using client object model, following code will be
used.
//Delete
the Permission for the user or Group
fileitem.RoleAssignments.GetByPrincipal(rcmGroupInfo).DeleteObject();
clientContext.ExecuteQuery();
Elevated
privileges
RunWithElevatedPrivileges
is not available in the client object model and hence user
context cannot be elevated to run the code.
To
download a file from document library
Server
side code
Using
SpFile.OpenBinaryStream method
using
(SPWeb
web = site.OpenWeb())
{
SPFile
file = web.GetFile(“/documents/testdocument.docx”);
System.IO.Stream
strm = file.OpenBinaryStream();
}
Client code
Client OM
doesn’t have the method with File object and hence need to use
FileInformation class.
FileInformation
has OpenBinaryDirect method to get the stream without
executing the query.
ClientContext
clientContext = new
ClientContext("http://SpSiteUrl");
Site
site = clientContext.Site;
//
Execute the query before getting the stream to create the context
clientContext.ExecuteQuery();
//
Get the file stream, This directly calls and get the file stream.
Need NOT call Excecute query
FileInformation
fileInfo =
Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext,
"/Documents/
Technical%20Design.docx");
//
Access the stream for further processin
System.IO.Stream
stream = fileInfo.Stream;