前面过了一下Sharepoint的服务器端对象模型,接下来就让我们大致看看Sharepoint的客户端对象模型(Client Object Model: Client OM)。
首先需要了解的就是Sharepoint的客户端模型是在Sharepoint2010才开始引入的,之前没有这个概念。
一、为什么要引入客户端对象模型呢?
这是因为随着Sharepoint的推广,人们发现有时需要从客户端计算机或服务器远程访问Sharepoint网站和它的列表数据,这些客户端计算机或服务器上并没有安装Sharepoint Fundation,也就是一个非常普通的环境,这样的环境要访问Sharepoint这样一个特殊平台上的资源,如果没有一种中间层作支持那是几乎做不到的(当然,您可以使用 Web 服务与 SharePoint 列表和其他功能进行交互,但这并非易事。如果 Web 服务不提供必需的功能,您可以编写服务器端代码来提供新的 Web 服务,这是一项更为困难的任务。有些 IT 部门不允许使用服务器端代码,或者只允许使用 IT 部门编写的代码,因此有时这并不可行)。所以,Sharepoint就引入了客户端对象模型,基于此客户端对象模型向开发者提供了相应的API来支持他们实现对远程Sharepoint资源的访问。其访问的方式可以是客户端计算机上的Windows应用程序、某个Silverlight 应用程序或Sharepoint的某个Custom Web Parts页,如下图所示:
客户端对象模型的引入就解决了上图中客户端程序如何理解Sharepoint对象模型的问题,有了Sharepoint对象模型的理解,才有了针对这些Sharepoint对象的操作,即:您可以添加和删除列表,添加、更新和删除列表项,更改文档库中的文档,创建网站,管理项目权限,以及在页面中添加和删除 Web 部件等等。
二、Sharepoint客户端对象模型都有哪些,并都提供了哪些API呢?
Microsoft SharePoint 2010 软件开发工具包 (SDK) 介绍了三种客户端 API,这些 API 允许您通过在
1、浏览器中执行的脚本(ECMScript:Javascript,JScript)
2、在 .NET 托管应用程序中执行的代码(Microsoft .NET Framework 3.5 或更高版本)
3、Microsoft Silverlight 2.0 应用程序
执行的代码与 SharePoint 网站进行交互。
与上述三种API对应的分别是三种客户端对象模型:
1、ECMAScript(JavaScript、JScript) 客户端对象模型
2、.NET 托管客户端对象模型
3、Silverlight 客户端对象模型
上述三种客户端对象模型均提供在 Microsoft.SharePoint.dll 中定义的服务器对象模型的子集,其中包括与 SharePoint Foundation 层次结构中的网站集(Site Collection)级别或更低级别的主要对象相对应的对象。为了提高安全性和性能,客户端对象模型将重点放在与客户端开发最为相关的 API 上,并且不包含在服务器对象模型中表示的所有类型和成员。
Sharepoin的这三类客户端对象模型共享结构设计特征,例如对象模型层次结构、对象标识、数据检索语义、客户端上下文、基础结构客户端对象、集和异常处理。这些对象模型与 SharePoint Foundation 服务器对象模型一致,因此,如果您熟悉服务器端 API,则可以很快学会使用客户端 .NET 托管 API、Silverlight API 或 JavaScript API。尽管客户端对象模型与服务器对象模型并不是相似的,但它们自身之间通常是彼此相似的,因此,当您掌握服务器对象模型的一个子集之后,也就掌握了其他子集的大部分内容。只要有可能,新的对象模型就会借用 .NET Framework(尤其是 ADO.NET)中的异步范例。
注: Windows Phone 7不支持Sharepoint中Silverlight 客户端对象模型
三、Sharepoint客户端对象模型是怎么工作的呢?
上面的示意图左边是客户端环境,右边是Sharepoint服务器端环境。
客户端环境运行的应用程序是通过客户端对象模型提供的API来与Sharepoint的资源打交道的,它们有多种方式(Client OM)与 API 进行交互,这种交互涉及多方面的内容,比如:
.调用API提供的方法并获取返回值
.传递协作应用程序标记语言 (CAML) 查询并获取结果
.设置或获取属性
使用 API 执行特定任务后,客户端对象模型会将使用的这些 API 捆绑到 XML 并发送给运行 SharePoint Foundation 的服务器。也就是说发送给Sharepoint服务器的访问请求是以XML格式传递的,因此上图中表示为XML Request。
服务器在收到该请求(XML Request)后,会调用服务器上适当的对象模型(Server OM),收集响应,将响应组成 JavaScript 对象标注 (JSON),然后将 JSON 发送回 SharePoint Foundation 2010 托管客户端对象模型。客户端对象模型随后分析 JSON 并将结果作为 .NET Framework 对象(或 JavaScript 的 JavaScript 对象)提供给应用程序。
所以,客户端是以XML形式提交请求,服务器端是以JSON形式返回请求结果。客户端应用程序是直接与客户端对象模型打交道,服务器端是直接与服务器端对象模型打交道。
必须注意,您需要控制客户端对象模型何时开始向服务器发送 XML 以及何时从服务器接收 JSON。
是否将对服务器的多次方法调用捆绑为单次调用由网络速度、网络延迟和所需的性能特性决定。如果客户端对象模型在每次调用方法时都与服务器交互,系统性能将会降低,网络流量会增大,从而导致系统不稳定。
您可以明确控制客户端对象模型何时捆绑方法调用以及向服务器发送请求。在此过程中,在启动与服务器的交互之前,您必须明确指定希望从服务器检索哪些内容。这是客户端对象模型与服务器端对象模型的最大区别。
四、客户端应用程序是如何获取客户端对象模型的呢?
上图说到客户端应用程序通过客户端对象模型与Sharepoint服务器端打交道,那么客户端应用程序如何才拥有Sharepoint客户端对象模型呢?
事实上,如果你的客户端应用程序想要使用客户端对象模型,您可获取适当的 .dll 或 .js 文件的本地副本,因为Sharepoint的客户端对象模型就是通过这些"代理 .js" 和"托管 .dll" 文件提供给客户端应用程序的。
所以,Sharepoin的客户端对象模型是分别通过代理 .js 和托管 .dll 文件提供出来的,你可在自定义应用程序(例如其他对象模型)中引用这些对象模型。这些对象模型作为 Windows Communication Foundation (WCF) 服务 (.../_vti_bin/client.svc) 来实现,但使用 Web 绑定来实现有效的请求批处理。所有操作实际上均为异步操作,命令被序列化到 XML 中,并通过一个 HTTP 请求发送到服务器。对于每个命令,会进行相应的服务器对象模型调用,并且服务器会向客户端返回一个 JavaScript Object Notation(或 JSON)压缩格式的响应,代理会分析此响应并将其与适当对象相关联,这就是我们在上面叙述过的。
下面分情况来看如何获取这些.dll 或 .js 文件的本地副本:
1、如果是开发基于.NET的应用程序
Microsoft SharePoint Foundation 2010 在 %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\ISAPI 中安装了 Microsoft.SharePoint.Client.dll 和 Microsoft.SharePoint.Client.Runtime.dll.
若要使 你开发的Windows 窗体、Windows Presentation Foundation (WPF) 或其他调用 .NET 托管 SharePoint Foundation 客户端 API 的应用程序能正常工作,则客户端计算机必须已安装 (引用)上述位置的SharePoint Foundation 客户端 DLL ,你必须同时具有 Microsoft.SharePoint.Client.dll 和 Microsoft.SharePoint.Client.Runtime.dll 才能使用 .NET 托管对象模型远程开发解决方案。也就是说:若要在客户端计算机上使用包含 .NET 托管客户端 API 的 DLL,必须使用 Microsoft 的 随应用程序一起分发它们。
2、如果是开发Silverlight应用程序
对于 Silverlight 客户端,Microsoft SharePoint Foundation 2010 将 Microsoft.SharePoint.Client.Silverlight.dll 和 Microsoft.SharePoint.Client.Silverlight.Runtime.dll 部署到特殊的只限脚本的文件夹 %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\ClientBin 中。此文件夹是用于承载在 Silverlight 中使用的程序集(此程序集包含在文件Microsoft.SharePoint.Client.xap中)的一个标准位置。必须同时具有 Microsoft.SharePoint.Client.Silverlight.dll 和 Microsoft.SharePoint.Client.Silverlight.Runtime.dll 才能使用 Silverlight 对象模型远程开发解决方案。
Silverlight 开发人员可以有两种选择:
一是将客户端 DLL(Microsoft.SharePoint.Client.Silverlight.dll 和 Microsoft.SharePoint.Client.Silverlight.Runtime.dll) 与你的Silverlight的 .xap 文件打包在一起以便下载。
另一个就是在运行时加载上面提到的Microsoft.SharePoint.Client.xap文件,因为这个文件中包含了客户端 DLL(Microsoft.SharePoint.Client.Silverlight.dll 和 Microsoft.SharePoint.Client.Silverlight.Runtime.dll)。
Microsoft SharePoint Foundation 2010 支持在两类上下文中实现 Silverlight 客户端对象模型:Silverlight Web 部件和 Silverlight 跨域数据访问系统(Silverlight 应用程序可通过此系统与 Microsoft SharePoint Foundation 2010 数据进行交互)。第三种可能的做法是修改服务器上的客户端访问跨域策略,但这将导致安全风险,因此 SharePoint Foundation 2010 中不支持此做法。
3、如果是开发基于ECMAScript的页面应用
ECMAScript(JavaScript、JScript) 客户端对象模型的缩小的 .js 文件(例如 SP.js、SP.Core.js、SP.Ribbon.js 和 SP.Runtime.js)安装在 %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS 目录下。当客户端计算机浏览到使用标准 SharePoint Foundation 母版页的任意 SharePoint Foundation 页时,会将这些 .js 文件下载到客户端。也就是说:包含 JavaScript 客户端 API 的 .js 文件在标准 SharePoint Foundation 母版页上引用,因此它们会自动下载到客户端并支持客户端使用其客户端对象模型。
若要使用自定义母版页,则在使用客户端对象模型时,母版页或内容页必须引用这些 .js 文件。
SharePoint Foundation 还会在相同目录下安装未缩小的、调试版本的 .js 文件,如 SP.debug.js、SP.Core.debug.js、SP.Ribbon.debug.js 和 SP.Runtime.debug.js,并且您可以指定是否使用调试版。
SharePoint Foundation 中的默认母版页在网页中插入一个 ScriptManager 控件,并且默认将此控件的 ScriptMode 属性设置为 Auto。通过将 <deployment retail="false" /> 添加到 web.config 文件(位于 %inetpub%\wwwroot\wss\VirtualDirectories\80 目录中)的 system.web 节中,可以替代此默认设置并使用调试 .js 文件。
ECMAScript(JavaScript、JScript)对象模型是随.NET 托管客户端对象模型和 Silverlight 客户端对象模型一起引入 Microsoft SharePoint Foundation 2010 中的。通过 JavaScript 对象模型,您无需在服务器上部署代码即可使用对象。在部署沙盒解决方案或使用服务器功能区时,能够在客户端处理对象会非常有用。由于 JavaScript 的特性,所有代码都异步执行并依赖回调函数来使用 SharePoint Foundation 2010 内的对象。JavaScript 只能处理当前上下文中的对象,即,无法进行跨站点脚本编写,或访问当前上下文外部的对象。
为了最大限度地减轻服务器的负荷,在创建对象时并不会加载所有对象属性。您必须使用 Include 语句和 load(clientObject) (该链接可能指向英文页面) 函数请求特定属性。
JavaScript 不支持托管客户端对象模型中的属性。JavaScript 对象模型使用前面带有 set_ 和 get_ 的方法,根据检索或设置属性的值的能力来公开相应属性。
下面的列表显示了在 /_layouts 文件夹中安装的重要的调试 .js 文件:
- SP.debug.js
- SP.Core.debug.js
- SP.Ribbon.debug.js
- SP.Runtime.debug.js
- JsGrid.debug.js
- JsGrid.Gantt.debug.js
五、关于客户端对象模型的命名空间:
Microsoft.SharePoint.Client 是用于 .NET 托管对象模型和 Silverlight 对象模型的核心命名空间,
SP是用于 ECMAScript(JavaScript、JScript) 对象模型的核心命名空间。
客户端对象模型及其相应的集合对象继承自 ClientObject (JavaScript: ClientObject) 和 ClientObjectCollection (JavaScript: ClientObjectCollection) 类。
除核心命名空间外,Microsoft SharePoint Foundation 2010 还提供以下命名空间:
下表显示了Sharepoint客户端对象模型的 API 为常见 SharePoint Foundation 2010 服务器对象提供的等效对象。
Sharepoint客户端对象模型的 API不提供管理对象或范围超出网站集(Site Collection)的对象,即服务器对象模型中的 SPSite 类。
六、关于作为中心对象的客户端上下文(ClientContext)
在使用服务器端对象模型编程时我们都知道有一个SPContext对象,类似,Sharepoint的客户端对象模型使用 ClientContext 对象作为所有操作的"引力中心"。
在获取并使用网站和数据的过程中,首先将检索上下文对象。例如,ClientContext clientContext = new ClientContext("http://MyServer/sites/MySiteCollection") 将实例化特定网站集的上下文对象。
ClientContext 对象 (JavaScript: ClientContext ) 将作为用于处理客户端对象模型的主入口点,并作为在网站集中安排请求和启动操作所借助的中央对象。使用 ClientContext 对象 (JavaScript: ClientContext) 的对象属性可获取网站集或网站(可通过其远程访问其他 SharePoint Foundation 客户端对象)。
ClientContext() 构造函数 (JavaScript: ClientContext(serverRelativeUrl)) 基于指定的网站或网站集初始化客户端上下文。在托管的客户端对象模型中,此 URL 必须是特定网站的绝对 URL。在 ECMAScript(JavaScript、JScript) 对象模型中,要么使用服务器的相对 URL,要么不使用任何参数。在 JavaScript 中,如果使用未采用任何参数的构造函数,则目标网站的 URL 为包含该网页的网站的 URL。
在实际执行查询之前,可使用通过客户端上下文返回的对象来定义要执行的操作。ClientContext 类 (JavaScript: ClientContext) 从 ClientRuntimeContext 类 (JavaScript: ClientRuntimeContext) 继承 Load<T>(T, Expression<Func<T, Object>>[]) (JavaScript: load(clientObject)) 和 LoadQuery() (JavaScript: loadQuery(clientObjectCollection, exp)) 方法。定义一个查询以执行特定操作并返回特定对象或属性,然后调用其中的某个方法来加载此查询。
在加载查询后,调用 ClientContext 对象 (JavaScript: ClientContext) 的 ExecuteQuery() 或 ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) 方法 (JavaScript: executeQueryAsync(succeededCallback, failedCallback)) 以将查询发送到服务器。Silverlight 客户端对象模型提供一个 ExecuteQuery() 方法(可从不会修改用户界面 (UI) 的线程同步调用此方法)和一个异步 ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) 方法(用于线程不会修改 UI 的情况)。这些用于执行查询的方法将表述表示对客户端执行的操作的 XML,并将此 XML 发送到服务器。在托管对象模型中,此调用是同步的,这表示在收到来自服务器的响应之前将组织代码执行。此调用在 Silverlight 对象模型中可以是同步的或异步的,而在 JavaScript 对象模型中始终是异步的。在异步调用中,代码将继续执行而不会等待服务器响应。在 Silverlight 对象模型和 JavaScript 对象模型中,可以实现在收到服务器响应时调用的回调函数。
在 SharePoint Foundation Silverlight 和 JavaScript 对象模型中,可以使用客户端上下文的 Current 属性 (JavaScript: current) 从 SharePoint Foundation 中运行的页面返回当前请求上下文。