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
SPWeb
SPList
SPListItem
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
Every time when you need to read the property, the object on which the property belongs needs to be executed. Multiple round trips to server which impacts performance
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 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;
2 comments:
Hi, I am using below code to get list item properties in javascript.
when we select list item in sharepoint list. It will call below function internally to get properties of targetListItem. Some times i am getting uniqueItemID and documentGuid null. If i click second time it is loading uniqueItemID and documentGuid property. Can you please help regarding this
var Listitem = selectedItems[0].id;
var targetList = clientContext.get_web().get_lists().getById(listId);
targetListItem = targetList.getItemById(Listitem);
clientContext.load(targetListItem);
function onQuerySucceeded(sender, args) {
try {
var listItemInfo = '';
uniqueItemID = targetListItem.get_item('UniqueId');
documentGuid = targetListItem.get_item('DocumentGUID');
}
catch (error) {
}
Very helpful post. I was able to use it successfully. Thanks.
Post a Comment