【IT168 技术】随着 Office 365 的发布,Microsoft 将推出 Microsoft Online Services 的下一版本,它是一种建立在 SharePoint 2010、Exchange 2010 和 Lync Server 2010 之上的、基于云的协作与通信服务。 Office 365(当前还处在测试版阶段)将作为一种基于订阅的“软件即服务”(SaaS) 产品提供 SharePoint、Exchange 和 Lync,托管在由 Microsoft 管理的云数据中心。
SharePoint Online 是 SharePoint 2010 的基于云的版本,它将为用户提供 SharePoint 2010 也具备的许多功能,但是无需管理可缩放且安全的协作解决方案所需的硬件或软件。 在本文中,我将通过构建一些在 SharePoint Online 中运行的解决方案,来概述 SharePoint Online 开发与 SharePoint 2010 开发之间的异同之处。
随着 SharePoint Online 的下一版本的推出,SharePoint 开发人员将能够使用他们在面向 SharePoint 2010 进行开发时所使用的技术和工具(包括 Visual Studio 2010、SharePoint Designer 2010、C# 或 Visual Basic、SharePoint API 以及 SDK)来开发协作解决方案。 虽然面向内部部署的 SharePoint 和面向云中的 SharePoint 的开发有许多相似之处,但两者也有很大的区别,这些区别将会影响您构建解决方案的方式。
了解这些区别将有助于您理解可以创建哪些在 SharePoint Online 中运行的解决方案以及如何开发这些解决方案。
SharePoint Online 自定义相似之处
在 SharePoint 2010 开发中,您可以通过使用浏览器和 SharePoint Designer 2010 以及使用 Visual Studio 2010 构建解决方案来自定义 SharePoint。 对于 SharePoint Online,除了下一部分介绍的功能区别之外,使用浏览器和 SharePoint Designer 2010 进行自定义与使用 SharePoint 2010 进行自定义的情况大致相同。 使用 Visual Studio 2010 开发 SharePoint Online 解决方案也大致相同。 开发是在 Visual Studio 2010 中针对 SharePoint 2010(在 Windows 7 或 Windows Server 2008 R2 中本地运行,或者在虚拟机(简称 VM)中本地运行)的一个本地实例进行的,利用了适用于迭代开发的集成调试体验。 完成开发后,使用 SharePoint 2010 中提供的相同解决方案库将该解决方案上载到 SharePoint Online 中。
SharePoint Online 自定义主要区别
虽然 SharePoint Online 基于 SharePoint 2010,但当您开发将在 SharePoint Online 中运行的解决方案时还需要注意一些主要区别。 首先,SharePoint Online 只支持作用域为站点和 Web 的解决方案。 SharePoint Online 在多用户云中运行,在该云中多个用户在一个共享的数据中心基础结构上运行,因此它不支持作用域为场(为整个场激活功能)的解决方案也是可以理解的。 同样,在 SharePoint Online 中,对您的 SharePoint 用户的最高访问级别是站点集合级别,因此它也不支持作用域为 WebApplication 的功能(其中某项功能在 Web 应用程序中的每个网站中运行)。
其次,SharePoint Online 只支持部分信任的解决方案, 不支持完全信任解决方案,完全信任解决方案是指拥有超越站点集合级别的访问权限或可以被授权在场上使用管理员级别权限运行的解决方案。
最后,虽然 SharePoint Online 基于 SharePoint 2010,但它与它的对应内部部署应用程序在功能上并不是完全相同的。 要了解 SharePoint 2010 与 SharePoint Online 之间的完整功能比较,请参阅“Office 365 Beta Service Descriptions”页面(网址为 bit.ly/bBckol)上的“Microsoft SharePoint Online Beta Service Description”。
从功能列表可以看出,大多数 SharePoint 自定义功能都受支持。 不支持业务连接服务 (BCS)、外部列表以及在 SharePoint Online 外部调用 Web 服务的能力(在部分信任的解决方案中不支持从外部调用 Web 服务)将会对构建能够在 SharePoint Online 中运行的解决方案产生巨大影响。 然而,计划在未来版本中支持 BCS。
了解这些相似之处和区别之后,让我们来看一些您能够构建以在 SharePoint Online 中运行的解决方案的例子,包括沙盒解决方案和 SharePoint 客户端对象模型 (OM)。 其他类型的解决方案,如通过声明性工作流解决方案自动执行业务流程,将会在以后的文章中介绍。
使用沙盒解决方案进行面向 SharePoint Online 的开发
在上文中,您了解到必须将 SharePoint Online 解决方案的作用域设定为站点或 Web 功能,这些解决方案只能使用站点集合中的数据,并且必须在部分信任环境中运行。 开发作为沙盒解决方案运行的解决方案可以满足所有这些标准,同时还可以允许 SharePoint Online 管理员通过将解决方案直接上载到解决方案库中来轻松部署解决方案。
Visual Studio 2010 为沙盒解决方案提供强大支持,包括项目模板和项目项模板支持、用于以沙盒解决方案的方式创建新项目的 SharePoint 自定义向导、针对作用域为站点集合的 SharePoint API 的 IntelliSense 支持以及调试和打包支持。 要为 SharePoint Online 构建一个解决方案,您将基于 SharePoint 2010 在本地开发和调试解决方案。 您将需要同时安装 Windows 7(64 位)或 Windows Server 2008 R2 以及 SharePoint 2010 和 Visual Studio 2010。 另一个好方法是使用 2010 Information Worker Demonstration and Evaluation Virtual Machine (RTM),该工具提供一个虚拟的 SharePoint 2010 开发环境(可从 bit.ly/ezfe2Y 下载该工具。) 我还建议使用 Visual Studio 2010 SharePoint Power 工具 (bit.ly/azq882),该工具添加了针对沙盒的编译时支持以及经过沙盒处理的可视 Web 部件项目项模板。
在本文的示例中,我将以使虚构的 Contoso Corp. 公司的员工能够 请求其采购系统中不支持的采购这个简单的情形为例,来讲述如何构建解决方案。 首先,我将在我的内部部署 SharePoint 2010 开发环境中创建一个站点集合和一个站点。 我使用的是之前所提到的 VM,因此我已经创建了 http://o365dpe.contoso.com/sites/spomsdnmag/purchasing。 我的第一个解决方案将部署用于跟踪这些非标准采购的列表。 我将打开 Visual Studio 2010,选择“文件”|“新建项目”,在“新建项目”对话框中,我将选择“空白 SharePoint 项目”,并将该项目命名为 PurchasingMgr。
在“SharePoint 自定义向导”对话框中,在“您想使用哪个本地站点进行调试?”中,我将输入我站点的 URL(即 http://o365dpe.contoso.com/sites/spomsdnmag/Purchasing/),选择“作为沙盒解决方案部署”,然后单击“完成”,如图 1 所示:
▲PurchasingMgr 指定站点和信任级别
接下来,我将在解决方案资源管理器中选择 PurchasingMgr 项目,右键单击,然后选择“添加”|“新项”。 在“添加新项”对话框中,我将在支持的 SharePoint 项模板的“已安装的模板”节点中选择“SharePoint 2010”。 在沙盒解决方案中,并非所有这些模板都受支持,因而这些模板在 SharePoint Online 中也并非都受支持。
▲图 2 显示了沙盒解决方案支持的项模板
为了构建我的列表,我将通过选择“内容类型”项模板,然后输入 NonStandBusPurchaseRequestsCT 作为其名称,来定义列表的站点列和内容类型。
在“SharePoint 自定义向导”中,我将选择“项”作为基础内容类型,然后单击“完成”。 内容类型将包含一个标题列、一个描述列和一个价格列,我将通过使用图 3 中的 XML 替换创建的 Elements.xml 的内容来以声明的方式定义这些列。
图 3 通过 Elements.xml 定义 NonStandBusPurchaseRequestsCT
在“SharePoint 自定义向导”中,我将选择之前创建的内容类型,然后选中“添加列表实例”框。 为 NonStandBusPurchaseRequestsListDefn 创建的 Elements.xml 如图 4 所示。
请注意,对于我的功能中的各个列表定义,都需要用一个大于 10,000 的唯一 Type 值来标识(以免与 SharePoint 定义的列表发生冲突),并且我要用该值来定义基于该定义的任何列表实例。
为了向列表视图中添加自定义栏,我将打开创建的 Schema.xml,然后向默认视图中添加 FieldRef 元素,如图 5 所示。
▲图 5 向 NonStandBusPurchaseRequestsListDefn 默认视图添加自定义栏
最后,我将通过选择 NonStandBusPurchaseRequestsListDefn 下的 ListInstance1 来定义列表实例,并将其重命名为 NonStandBusPurchaseRequestsListInstance。 我将打开 Elements.xml 并添加以下 XML,使列表基于内容类型,并为用户提供有用的说明:
在 Visual Studio 2010 中,我将选择“调试”,然后选择“启动调试”来测试解决方案。 解决方案是打包的解决方案,已部署到了我的内部部署站点,如图 6 所示。
▲ 图 6 调试 PurchasingMgr 解决方案
现在我已经测试了 PurchasingMgr 解决方案,可以将其部署到 SharePoint Online。 我将使用工作组网站模板在 SharePoint Online 中创建一个名为 Purchasing 的新网站集。 回到 Visual Studio 2010,我将通过在“解决方案资源管理器”中右键单击 PurchasingMgr 项目,然后选择“打包”,来对解决方案进行打包。 要将解决方案部署到 SharePoint Online,我只需要将其上载到解决方案库,然后激活网站功能(我需要拥有网站集管理员权限才能执行此操作)即可。 为此,我需要登录 SharePoint Online,导航到我的网站集,选择“网站操作”|“网站设置”,然后选择“解决方案”以访问解决方案库。 在解决方案库中,我将单击“解决方案”选项卡,在功能区中选择“上载解决方案”,然后在 bin\Debug 中浏览至 PurchasingMgr.wsp 文件,单击“确定”,然后单击“激活”。 您将在解决方案库中看到您的解决方案,如图 7 所示。
▲图 7 部署到 SharePoint Online 的 PurchasingMgr 解决方案
接下来,为了激活包含我的网站栏、内容类型和列表的功能,我将导航到 Purchasing 站点,然后选择“网站操作”|“网站设置”|“管理网站功能”。 我将选择“Purchasing Manager – 内容类型和列表”功能,然后选择“激活”。 此时,您将在您的 SharePoint Online 站点中看到“非标准业务购买请求”列表。
Purchasing Manager 只是您可以在 SharePoint Online 中使用沙盒解决方案实现的一个示例。 请记住沙盒解决方案和支持 SharePoint Online 的功能中存在的限制,而且您可以创建在 SharePoint 2010 或 SharePoint Online 中运行的解决方案。
使用 Silverlight 创建客户端解决方案
客户端 OM(随 SharePoint 2010 推出)为使用 Microsoft .NET Framework、Silverlight 和 ECMAScript(包括 JavaScript 和 JScript)构建的 SharePoint 客户端(在包括适用于 Silverlight 和 ECMAScript 的浏览器的远程计算机上运行)提供了一种面向对象的客户端 API。 该 API 与 Microsoft.SharePoint 服务器端命名空间是一致的,因此学习起来很容易。 该 API 在受支持的客户端类型中也都是一致的,因此您可以轻松地将这些知识应用于不同的客户端解决方案。 SharePoint Online 支持客户端 OM API,客户端 OM API 是一种用于云开发的有力工具。
例如,我可以使用客户端 OM 创建 Silverlight 4 应用程序,以便向我的列表中添加项目并在沙盒 Web 部件中承载该应用程序。 为此,我将打开 Visual Studio 2010,选择“文件”|“新建项目”,然后在“新建项目”对话框中选择“空白 SharePoint 项目”。 我将该项目命名为“PurchasingMgrWP”,然后单击“确定”。 此外,我将创建一个沙盒解决方案形式的解决方案,并使其指向我的内部部署 Purchasing 站点。 为了创建 Silverlight 4 应用程序,我将右键单击 PurchasingMgrWP 解决方案,在“已安装的模板”下选择“Silverlight”,选择“Silverlight 应用程序”,然后将该解决方案命名为 NonStandBusPurchaseReqsSLOM。 在“新建 Silverlight 应用程序”对话框中,我将取消选中“在新网站中承载 Silverlight 应用程序”(我们将通过在 SharePoint 中承载该应用程序进行测试),然后为“Silverlight 版本”选择“Silverlight 4”。
为了引用 Silverlight 客户端 OM API,我将在 C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin 中添加对 Microsoft.SharePoint.Client.Silverlight.dll 和 Microsoft.SharePoint.Client.Silverlight.Runtime.dll 的引用。 接下来,我将通过打开 MainPage.xaml 并使用图 8 中的代码替换 XAML 来创建 Silverlight UI。
▲图 8 NonStandBusPurchaseReqsSLOM MainPage.xaml
图 8 中的 XAML 定义了文本框和一个按钮,该按钮用于收集要添加到我的列表中的信息,如图 9 所示
图 9 设计器中的 MainPage.xaml
在设计器中双击该按钮并使用图 10 中的代码替换类。
图 10 addNonStanPurchaseReq_Click
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.SharePoint.Client;
namespace NonStandBusPurchaseReqsSLOM
{
public partial class MainPage : UserControl
{
private string webUrl;
public MainPage(string url)
{
webUrl = url;
InitializeComponent();
}
private void addNonStanPurchaseReq_Click(object sender, RoutedEventArgs e)
{
ClientContext clientContext = new ClientContext(webUrl);
Web webSite = clientContext.Web;
ListCollection webLists = webSite.Lists;
List nonStandBusPurList =
clientContext.Web.Lists.GetByTitle(
"Non-Standard Business Purchase Requests");
ListItem newListItem =
nonStandBusPurList.AddItem(new ListItemCreationInformation());
newListItem["Title"] = Title.Text;
newListItem["RequestDescription"] = Description.Text;
newListItem["Price"] = Price.Text;
newListItem.Update();
clientContext.Load(nonStandBusPurList, list => list.Title);
clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);
}
private void onQuerySucceeded(
object sender, ClientRequestSucceededEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("New item added.");
});
}
private void onQueryFailed(object sender,
ClientRequestFailedEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Request failed. "
+ args.Message + "\n" +
args.StackTrace);
});
}
}
}
图 10 中的代码遵循客户端 OM 代码的通用模式。首先,我将通过 ClientContext 类(与 SPContext 类等效)访问客户端上下文。接下来,我将分别通过 Web、ListCollection 和 List 类来访问网站和列表。请注意 SPWeb、SPListCollection 和 SPList 类的相似之处。最后,我将通过调用 List.AddItem 方法创建一个 ListItem,使用 UI 中的数据填充 ListItem,然后调用 ListItem.Update 方法。在调用 ClientContext.Load 和 ClientContext.ExecuteQueryAsync 方法来执行查询之前,不会实际创建 ListItem。请注意,您可以通过以下做法来避免与服务器之间的来回操作: 通过 ClientContext.Load 加载多个查询,调用 ClientContext.ExecuteQueryAsync 方法。
为了部署 Silverlight 4 应用程序,我将添加一个模块以使用我的 Web 部件项目部署该应用程序。我将在“解决方案资源管理器”中选择“PurchasingMgrWP”,右键单击并选择“添加”|“新建项目”|“模块”,然后将该模块命名为 ClientBin。我将使用以下 XML 替换创建的 Elements.xml 的内容:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="ClientBin">
<File Path="ClientBin\NonStandBusPurchaseReqsSLOM.xap"
Url="ClientBin/NonStandBusPurchaseReqsSLOM.xap" />
</Module>
</Elements>
此 XML 将把 NonStandBusPurchaseReqsSLOM.xap 文件部署到我的 SharePoint 网站的 ClientBin 文件夹中。
为了使用 ClientBin 模块部署 NonStandBusPurchaseReqsSLOM 项目的输出内容,我将在“解决方案资源管理器”中选择 ClientBin 模块,然后打开“项目输出引用”属性对话框。我将单击“添加”,然后选择“NonStandBusPurchaseReqsSLOM”作为项目名称,选择“ElementFile”作为部署类型。
接下来,我将向我的 SharePoint 解决方案中添加一个自定义的 Web 部件,以承载我的 Silverlight 4 应用程序。我将在“解决方案资源管理器”中选择“PurchasingMgrWP”,右键单击并选择“添加”|“新建项目”,选择“Web 部件”,然后将该 Web 部件命名为 NonStandBusPurchaseReqsWP。我将使用自定义 Web 部件来向我的 Silverlight 4 应用程序传递参数,例如用于创建 ClientContext 的站点的 URL。为此,我将添加一个名为 SilverlightObjectTagControl.cs 的帮助器类,并使用图 11 中的代码替换该类的内容。
图 11 添加 SilverlightObjectTagControl.cs 帮助器类
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace PurchasingMgrWP
{
class SilverlightObjectTagControl : WebControl
{
public string Source { get; set; }
public string InitParameters { get; set; }
protected override void CreateChildControls()
{
base.CreateChildControls();
if (Source != null && Source != "")
{
string width = (this.Width == Unit.Empty) ? "
400" :
this.Width.ToString();
string height = (this.Height == Unit.Empty) ? "
300" :
this.Height.ToString();
this.Controls.Add(new LiteralControl(
" <div>" +
" <object data=\"data:application/x-silverlight-2,\" +
" type=\"application/x-silverlight-2\" width=\"" + width +
" "\" height=\"" + height + "\">" +
" <param name=\"source\" value=\"" + Source + "\"/>" +
" <param name=\"onerror\" value=\"onSilverlightError\" />" +
" <param name=\"background\" value=\"white\" />" +
" <param name=\"minRuntimeVersion\" value=\"4.0.50826.0\" />" +
" <param name=\"autoUpgrade\" value=\"true\" />" +
" <param name=\"initparams\" value=\"" + InitParameters + "\" />" +
" <a href=\"http://go.microsoft.com/fwlink/?LinkID=" +
" 149156&v=4.0.50826.0\" +
" style=\"text-decoration: none;\">" +
" <img src=\"http://go.microsoft.com/fwlink/?LinkId=161376\" +
" alt=\"Get Microsoft Silverlight\" style=\"border-style: none\"/>" +
" </a>" +
" </object>" +
" <iframe id=\"_sl_historyFrame\" +
" style=.visibility:hidden;height:0;width:0;border:0px.></iframe>" +
" </div>"
));
}
}
}
}
图 11 中的 SilverlightObjectTagControl 类具有两个属性:Source 用于传递 Silverlight 应用程序的 URL 以加载 Web 部件,InitParameters 用于向 Silverlight 4 传递初始化参数。这两个属性在 CreateChildControls 方法中用于为 Silverlight 应用程序构建标记。要使用此类,请打开 NonStandBusPurchaseReqsWP.cs,然后用图 12 中的代码替换此类中的代码。
NonStandBusPurchaseReqsWP.cs
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace PurchasingMgrWP.NonStandBusPurchaseReqsWP
{
[ToolboxItemAttribute(false)]
public class NonStandBusPurchaseReqsWP : WebPart
{
protected override void CreateChildControls()
{
base.CreateChildControls();
SilverlightObjectTagControl slhc =
new SilverlightObjectTagControl();
slhc.Source = SPContext.Current.Site.Url +
"/ClientBin/NonStandBusPurchaseReqsSLOM.xap";
slhc.InitParameters = "url=" + SPContext.Current.Web.Url;
this.Controls.Add(slhc);
}
}
}
图 12 中的代码可以创建 SilverlightObjectTagControl 的实例,将 Source 属性设置为 Silverlight 应用程序在 ClientBin 中的 URL,设置 InitParameters 属性来存放当前站点(可在其中找到“非标准业务购买请求”列表)的 URL。要向 NonStandBusPurchaseReqsSLOM 中的 MainPage 类的构造函数传递 URL,打开 App.xaml.cs,然后将以下代码添加到 Application_Startup 事件中:
private void Application_Startup(object sender, StartupEventArgs e) { string url = e.InitParams["url"]; this.RootVisual = new MainPage(url); }
要测试 Web 部件,请将 PurchasingMgr.wsp 程序包部署到内部部署购买站点,以部署“非标准业务购买请求”列表(当前面列出的调试会话结束时,即会删除该列表),然后在 Visual Studio 2010 中调试 PurchasingMgrWP 解决方案。将 Web 部件添加到 \Purchasing\Home.aspx 中后,我就可以利用 Web 部件从 Silverlight 将项目直接添加到该列表中,如图 13 和图 14 所示。
图 13 运行中的 NonStandBusPurchaseReqsWP
图 14 更新后的“非标准业务购买请求”列表
基于内部部署站点进行开发和调试使我可以使用 Visual Studio 2010 来调试 SharePoint 和 Silverlight 4 代码,直至我测试完整个解决方案。此时,我要将 PurchasingMgrWP.wsp 上载到 SharePoint Online 中的解决方案库。
SharePoint 客户端 OM 提供了一种人们熟悉的、一致的面向对象的 API,用于访问 SharePoint Online 中的列表和库。该 API 是 Microsoft.SharePoint API 的一个子集,其作用域是网站集及其以下级别,这完全符合 SharePoint Online 开发工作的需要。
云中的 SharePoint 解决方案
综上所述,SharePoint Online 为 SharePoint 开发人员提供了一个少有的机会,使他们能够利用自己已经拥有的技能和工具来面向云构建 SharePoint 解决方案。理解了 SharePoint Online 自定义功能(包括支持的功能和不支持的功能)、沙盒解决方案、SharePoint 客户端 OM 和使用 SharePoint Designer 2010 构建的声明性工作流后,您便可以使用 SharePoint Online 构建在云中运行的 SharePoint 解决方案。要了解 SharePoint Online 开发在整个测试阶段的最新消息,请查看 SharePoint Online 开发人员资源中心 (msdn.com/sharepointonline)。