Sometimes in coding we need to make decision based on exception. For example the following code snippet try to enable versioning and folder creation in a list using SharePoint Client Object Model. However, if the list doesn’t exist then the code also create the list.
public static void EnableListVersioningAndFolderCreation(string siteUrl, string listName, string description) { using(var clientContext=new ClientContext(siteUrl)) { List list = null; try { list = clientContext.Web.Lists.GetByTitle(listName); clientContext.Load(list); clientContext.ExecuteQuery(); } catch (Exception) { var listCreationInformation=new ListCreationInformation(); listCreationInformation.Title = listName; listCreationInformation.TemplateType = (int)ListTemplateType.GenericList; listCreationInformation.Description = description; list = clientContext.Web.Lists.Add(listCreationInformation); clientContext.ExecuteQuery(); } finally { list.EnableVersioning = true; list.EnableFolderCreation = true; list.Update(); clientContext.ExecuteQuery(); } } }
Figure 1: Code snippet using Try/Catch/Finally approach
The above scenario is rife in SharePoint programming. Based on exception you get the sign that something is missing and you need to fill the missing part.
Problem with this try/catch/finally approach
The code block shown in Figure 1, is using try/catch/finally approach to apply logic. We can’t change the try/catch approach as for some SharePoint items there’s no way to find if the item (list, library, web) exists or not without getting an exception. So we decide based on exception. However, in Client Object Model we are concerned with the number of requests are sent to the server. In the code snippet of Figure 1, its obvious that the ClientContext.ExecuteQuery can be executed more than once. If ExecutedQuery method in try block is failed then the ExecutedQuery method in catch block is tried and at last finally block ExecutedQuery method is executed. It would be better if we could just call the ExecutedQuery once only. That’s what we are going to get with ExceptionHandlingScope. Also the code block will look much smarter and easier to read with ExceptionHandlingScope.
How to use ExceptionHandlingScope?
Unfortunately, ExceptionHandlingScope is available in Microsoft.SharePoint.Client namespace and targeted to use in SharePoint Client Object Model Programming. The Exception Handling Scope block starts with StartScope() method. Inside StartScope block, you will have three different sections: StartTry, StratCatch and StartFinally. In StartScope block the first block must be StartTry followed by StartCatch and then StartFinally. the basic structure is shown below:
var clientContext = new ClientContext("http://server/site"); var exceptionHandlingScope = new ExceptionHandlingScope(clientContext); using (exceptionHandlingScope.StartScope()) { using (exceptionHandlingScope.StartTry()) { //write code here that can throw exception. } using (exceptionHandlingScope.StartCatch()) { //if exception is thrown in StartTry block, control will be here. } using (exceptionHandlingScope.StartFinally()) { //this block will alwasy be executed } }
Figure 2: Exception Handling scope code block structure
Now the following code block is just like code snippet shown in Figure 1 but the following code block uses ExceptionHandlingScope.
public static void EnableListVersioningAndFolderCreation(string siteUrl, string listName, string description) { using (var clientContext = new ClientContext(siteUrl)) { var exceptionHandlingScope = new ExceptionHandlingScope(clientContext); List list; using (exceptionHandlingScope.StartScope()) { using (exceptionHandlingScope.StartTry()) { list = clientContext.Web.Lists.GetByTitle(listName); clientContext.Load(list); //clientContext.ExecuteQuery(); } using (exceptionHandlingScope.StartCatch()) { var listCreationInformation = new ListCreationInformation(); listCreationInformation.Title = listName; listCreationInformation.TemplateType = (int)ListTemplateType.GenericList; listCreationInformation.Description = description; list = clientContext.Web.Lists.Add(listCreationInformation); //clientContext.ExecuteQuery(); } using (exceptionHandlingScope.StartFinally()) { list.EnableVersioning = true; list.EnableFolderCreation = true; list.Update(); //clientContext.ExecuteQuery(); } } clientContext.ExecuteQuery(); } }
Figure 3: ExceptionHandlingScope in Action as a replacement of code snippet shown in Figure 1
As shown in figure 3, using ExceptionHandlingScope construct we can put the logic in different ExceptionHandlingScope block. Also the ExecuteQuery is executed only once. The following table shows the difference of try/catch/finally approach and ExceptionHandlingScope approach:
Try/Catch/Finally Approach |
ExceptionHandlingScope approach |
1.Sends more than one requests to the server. One in Try block. Another in Catch block if exception is thrown. And another one from finally block | 1. Only one request is sent to the server. Logics in ExceptionHandlingScope are packed together and sent to the server which is executed as a whole in a single request. |
2. Code looks much easier to read and understand. Though a bit uneasy for novice. | 2. Code looks not comfortable as good developers don’t like to write complex logic in catch block. |
3. Number of calls to ClientContexts gets higher which makes future modifications/debugging harder as developers need to find all the places from where calls are made to the server. | 3. Reducing number of calls to the server makes the debugging and modification easier. |
Conclusion
The overall benefits of using ExceptionHandlingScope are reduced number of calls to the server which in turn results rapid responsiveness and reduce load on server. So this ExceptionHandlingScope can be a handy for SharePoint developers.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.