• 使用ExceptionHandlingScope进行高效的SharePoint CSOM编程


    异常处理

    在我们使用SharePoint API的时候,获取某些对象的时候,可能会出异常,那么CSOM如何处理这种情况呢。

    我们在获取某个List的时候,代码如下:

                using (ClientContext clientContext = new ClientContext("https://cnblogtest.sharepoint.com"))
                {
    
                    var pasword = new SecureString();
    
                    "abc123!@#".ToCharArray().ToList().ForEach(pasword.AppendChar);
    
                    clientContext.Credentials = new SharePointOnlineCredentials("test001@cnblogtest.onmicrosoft.com", pasword);//设置权限
    
                    var currentWeb = clientContext.Web;
    
                    //此API调用时,如果此List在服务器端不存在,会出现异常。
                    var list = currentWeb.Lists.GetByTitle("Documents Test");
    
                    clientContext.Load(list);
                    clientContext.ExecuteQuery();//执行查询,返回异常
    
                }
    

      

    如果服务器端出现异常,服务器会把异常的相关信息通过JSON对象返回给CSOM端。这里面,我们截取异常的Response来看一下:

    这个JSON对象里面明确的显示了在执行GetListById的时候,返回的异常信息。

    当通过currentWeb.Lists.GetByTitle("Documents Test") 获取List的时候,如果服务器端如果不存在这个List,会出现异常。我们在写服务器端的应用程序的时候,只需要try catch就可以了,但是我们知道ClientAPI本身的调用时通过WCF来进行调用的,我们只有在执行了ExecuteQuery之后,才知道服务器端是否出现异常,然后服务器把异常信息包装后返回给CSOM。

    这种API的行为会给我们带来一系列的问题。如果我们在List不存在的时候,需要新建一个,如果通过不在CSOM引发异常的方式来执行呢?上面的例子中,如果我们在List不存在时新建一个List,仍然需要一次请求,如何能再一次请求中实现呢?

    使用ExceptionHandlingScope来提高CSOM程序的性能

    这个类就是我们用于处理服务器端异常的常用类。上面的例子中,我们可以用如下代码来实现。

                using (ClientContext clientContext = new ClientContext("https://cnblogtest.sharepoint.com"))
                {
                    var pasword = new SecureString();
                    "abc123!@#".ToCharArray().ToList().ForEach(pasword.AppendChar);
    
                    clientContext.Credentials = new SharePointOnlineCredentials("test001@cnblogtest.onmicrosoft.com", pasword);//设置权限
    
                    var currentWeb = clientContext.Web;
    
    
                    var exceptionHandlingScope = new ExceptionHandlingScope(clientContext);
    
                    //List list = null;
                    using (var currentScope = exceptionHandlingScope.StartScope())
                    {
                        using (exceptionHandlingScope.StartTry())
                        {
                            //此API调用时,如果此List在Server端不存在,会出现异常。
                            var listGetById = currentWeb.Lists.GetByTitle("Documents Test");
                            listGetById.Description = "List Get By Id";
                            listGetById.Update();
                        }
                        using (exceptionHandlingScope.StartCatch())
                        {
                            ListCreationInformation listCreationInfo = new ListCreationInformation();
                            listCreationInfo.Title = "Documents Test";
                            listCreationInfo.TemplateType = (int)ListTemplateType.DocumentLibrary;
                            listCreationInfo.Description = "List create in catch block";
                            currentWeb.Lists.Add(listCreationInfo);
                        }
                    }
    
                    List list = currentWeb.Lists.GetByTitle("Documents Test");
                    clientContext.Load(list);
                    clientContext.ExecuteQuery();//执行查询,不会出异常
    
                    //Server端是否出现了异常
                    Console.WriteLine("Server has Exception:" + exceptionHandlingScope.HasException);
                    //Server端异常信息
                    Console.WriteLine("Server Error Message:" + exceptionHandlingScope.ErrorMessage);
                }
    

      

    这个类解决了我们上面说的的问题,服务器端在编译的时候,会把ExceptionHandlingScope里面的代码编译成try catch这样的代码,因此我们可以通过一次请求来实现类似try catch这样的逻辑。

    上面的代码再已经CSOM编译后的请求报文为:

    <Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="15.0.0.0" ApplicationName=".NET Library" 
    xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009">
    <Actions>
    <ObjectPath Id="2" ObjectPathId="1" />
    <ObjectPath Id="4" ObjectPathId="3" />
    <ExceptionHandlingScope Id="5">
    <TryScope Id="7">
    <ObjectPath Id="10" ObjectPathId="9" />
    <ObjectPath Id="12" ObjectPathId="11" />
    <ObjectIdentityQuery Id="13" ObjectPathId="11" />
    </TryScope>
    <CatchScope Id="15">
    <ObjectPath Id="18" ObjectPathId="17" />
    <ObjectIdentityQuery Id="19" ObjectPathId="17" />
    </CatchScope>
    </ExceptionHandlingScope>
    <Query Id="22" ObjectPathId="11">
    <Query SelectAllProperties="true">
    <Properties />
    </Query>
    </Query>
    </Actions>
    <ObjectPaths>
    <StaticProperty Id="1" TypeId="{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}" Name="Current" />
    <Property Id="3" ParentId="1" Name="Web" />
    <Property Id="9" ParentId="3" Name="Lists" />
    <Method Id="11" ParentId="9" Name="GetByTitle">
    <Parameters>
    <Parameter Type="String">Documents Test</Parameter>
    </Parameters>
    </Method>
    <Method Id="17" ParentId="9" Name="Add">
    <Parameters>
    <Parameter TypeId="{e247b7fc-095e-4ea4-a4c9-c5d373723d8c}">
    <Property Name="CustomSchemaXml" Type="Null" />
    <Property Name="DataSourceProperties" Type="Dictionary" />
    <Property Name="Description" Type="Null" />
    <Property Name="DocumentTemplateType" Type="Int32">0</Property>
    <Property Name="QuickLaunchOption" Type="Enum">0</Property>
    <Property Name="TemplateFeatureId" Type="Guid">{00000000-0000-0000-0000-000000000000}</Property>
    <Property Name="TemplateType" Type="Int32">101</Property>
    <Property Name="Title" Type="String">Documents Test</Property>
    <Property Name="Url" Type="Null" />
    </Parameter>
    </Parameters>
    </Method>
    </ObjectPaths>
    </Request>
    View Code

    从这个报文,中我们已经可以大致看出CSOM如何表示这种try catch finally的代码块。我们可以看到ExceptionHandlingScope也是和ClientObject一样有Id信息,这样服务器端就可以把对应的代码编译成server端的try catch finally了。

    由于CSOM是基于http请求的,因此尽可能的减少请求,对于我们写出高效的程序至关重要。

    下一篇文章主要会介绍 ConditionalScope的使用。

  • 相关阅读:
    也谈谈我面试的经历
    synchronized和lock比对
    数据结构之查找
    iptable和tcpdump的先后顺序
    iptable的四表五链
    iptable规则的执行顺序
    curl指令的坑
    k8s 网络模型解析之实践
    如何创建一个img文件并且mount 它
    k8s 网络模型解析之原理
  • 原文地址:https://www.cnblogs.com/myprogram/p/3998138.html
Copyright © 2020-2023  润新知