使用 Visual Studio IDE 将您的 SharePoint 环境集成到基于开放标准的 WebSphere Portal 平台中





5.00/5 (2投票s)
介绍 Mainsoft 的 SharePoint Federator for WebSphere Portal,这是一个基于 Visual Studio® 的软件开发工具包 (SDK),它使您能够在 Microsoft® SharePoint 站点、.NET 和 Java™ 应用程序之间提供集成的用户体验,而无需牺牲工作组的自主性。
这是我们对 The Code Project 赞助商的展示性评测。这些评测旨在为您提供我们认为对开发人员有用且有价值的产品和服务信息。
引言
许多组织都有部门或单位在使用 Windows® SharePoint® Server 进行临时协作环境,而主要的企业门户基础设施则构建在 IBM WebSphere® Portal 之上。如果您发现自己处于这种情况,并且希望将 SharePoint 数据暴露给组织内外更广泛的受众,那么请继续阅读!
本文将向您介绍 Mainsoft 的 SharePoint Federator for WebSphere Portal,这是一个基于 Visual Studio® 的软件开发工具包 (SDK),它使您能够在 Microsoft® SharePoint 站点、.NET 和 Java™ 应用程序之间提供集成的用户体验,而无需牺牲工作组的自主性。您将学习如何利用您的 .NET 和 Visual Studio 专业知识,将 Windows SharePoint Services (WSS) 和 SharePoint 站点与运行在 WebSphere Portal 上的 Google Maps™ portlet 连接起来。
什么是 Mainsoft SharePoint Federator?
Mainsoft's SharePoint Federator for WebSphere Portal 是 Mainsoft's Portal Edition 的一个附加组件,它将联合的 SharePoint 内容与运行在 WebSphere Portal 上的 .NET 和 Java 应用程序集成在一起。它提供了现成的 portlet,可以轻松配置以暴露您的 SharePoint 文档库和 SharePoint 列表。这些 portlet 以源代码形式提供,可以根据您组织的特定需求进行定制。现在,您可以在单一登录、基于角色的环境中,通过单一的个性化访问点来访问您的企业应用程序和内容。将内容和服务联合到 WebSphere Portal 上可以进一步增强 SharePoint 的扩展能力,并与其遗留系统和后端系统集成。
SharePoint Federator SDK 的核心是两个 ASP.NET Web 控件(参见图 1)
- SharePointDataSource
- SaveCredentials
在 ASP.NET 表单中使用它们,您可以无缝访问您的 SharePoint 内容。您可以使用熟悉的 ASP.NET 开发框架将 SharePoint 数据呈现到您的 WebSphere Portal 环境中。
SharePointDataSource 控件具有一个设计时向导,用于配置您要连接的 SharePoint 服务器。在设计时,该控件允许您指定要检索的 SharePoint 列表或视图。它还允许您通过协作应用程序标记语言 (CAML)(用于查询 SharePoint 站点的基于 XML 的语言)深入了解数据并自定义要获取的列和行,以及定义排序顺序和结果集分组。您可以使用可视化设计器(参见图 2)或支持 IntelliSense 的 XML 编辑器来进行这些自定义。SharePointDataSource 控件的行为类似于您习惯的标准 DataSource 控件(例如 SqlDataSource 或 ObjectDataSource),可以轻松地在标准的 ASP.NET Web 数据绑定控件中查看 SharePoint 数据。
如果您在 WebSphere Portal 和 SharePoint 站点之间没有受信任的连接,用户或管理员将需要配置 SharePoint 凭据,以便在 SharePoint 站点上进行身份验证。您可以构建个性化或配置表单来捕获这些凭据,并将其存储在 WebSphere Portal Credential Vault 中。WebSphere Portal Credential Vault 是 Mainsoft 的 SharePoint Federator portlet 用于在不受信任的环境中安全存储和检索连接到 SharePoint 的凭据的门户服务。存储在 WebSphere Portal 中的凭据槽有两种类型:用户或管理员。使用用户 Credential Vault,您的 portlet 用户将在“编辑”表单中输入自己的凭据。使用管理员槽,您的门户管理员将能够为所有 portlet 用户配置共享凭据。SaveCredentials 控件(参见图 3)允许您在第一次访问时提示用户(或管理员)输入 SharePoint 凭据,并将其存储在 WebSphere 中,以便在未来的会话中进行单点登录。
SaveCredentials 控件通常添加到 portlet 的“编辑”模式页面。
在门户用户无需配置自己的 SharePoint 凭据即可访问 SharePoint 站点的情况下,共享的 Credential Vault 槽最适合使用。在某些情况下,您的公司门户用户可能无法直接访问部门 SharePoint 站点。然后,门户管理员可以使用共享凭据,并仅依赖 WebSphere Portal 身份验证来授权访问 SharePoint 数据。
您不限于使用可视化控件来访问当前登录的 SharePoint 用户的存储凭据。CredentialVaultSlot
类提供了对特定凭据库槽数据的简单访问点。这在您需要与使用 SharePoint 凭据的不同的后端系统(例如电子邮件服务器)进行身份验证,或者只是显示当前登录的 SharePoint 用户的用户名时非常有用。
CredentialVaultSlot cvs = CredentialVaultSlot.Open(PortletRequest, "SharePointAccess");
Label1.Text = cvs.Username;
将 SharePoint 内容呈现到 portlet 中的一个重要好处是,用户可以通过在同一页面上连接或组合不同的 portlet 来获得协同效应。例如,一个 portlet 可以显示项目列表,而第二个 portlet 显示所选项目的详细信息。这些连接称为 Portlet 间通信 (IPC),由门户用户定义。虽然 IPC 不是原始 JSR 168 portlet 规范的一部分,但它已集成到即将推出的 JSR 286 规范中,并且将成为 WebSphere Portal 最终用户体验的重要组成部分。
下面,我将向您展示如何将 SharePoint 内容集成到企业工作流中,基于一个虚构但现实的编码场景。示例应用程序将展示 SharePointDataSource、Credential Vaults 和 IPC 的实际应用。
SharePoint Federator 实际应用
一家大型律师事务所希望为辛勤工作的律师们的生活提供一些便利。资深合伙人决定使用他们的门户来展示公司的客户列表,并与 Google Maps 集成,提供与客户沟通的简单方式。尽管该公司使用 WebSphere Portal 提供门户解决方案,但他们使用 Microsoft SharePoint 来维护客户联系人列表。此外,内部 .NET 开发团队在 Visual Studio 方面经验丰富,并且该公司在新项目启动时,渴望充分利用他们对 Microsoft IDE 和框架的熟悉程度。
这个背景故事中的技术参数在当今许多组织中都是一个普遍的场景。
让我们来看看实际需求。为了使门户站点更加有用,同时又增加一些趣味性,页面将包含三个 portlet
- 律师事务所客户列表 - 使用 DataList .NET 控件列出客户。
- Google Maps - 用于使用 Google Maps JavaScript API 查看客户位置的地图。
- 联系信息 - 所选联系人的详细视图。用户可以使用存储在 SharePoint 中的信息直接联系客户。
通过连接这些 portlet,当用户选择不同的联系人时,地图和联系信息 portlet 将自动刷新。
此示例是用 Visual C#® 编写的,但就像 Mainsoft 的所有互操作性解决方案一样,使用 Visual Basic® 同样有效。
完整的源代码 可供下载。在构建和部署源代码之前,您必须修改连接字符串以指向您自己的 SharePoint 服务器。连接字符串存储在 Web.config 文件中。
让我们开始启动 Visual Studio,其中已安装 Mainsoft 的 Portal Edition。如果您还没有安装 Mainsoft 的 Visual Studio 插件,您可以下载一个功能完整的 30 天试用版。我首先使用“Visual C# for Java EE”(参见图 4)下的模板“ASP.NET Portal Application”创建一个新项目。Mainsoft 的插件还允许您采用现有的 ASP.NET 解决方案,并将其作为 Java EE 应用程序部署到 WebSphere Portal。要了解有关将现有 .NET 项目转换为 Java 的更多信息,请阅读文章 “使用 Visual Studio IDE 创建 WebSphere Portal 应用”。
将主 portlet 连接到带有客户联系人详细信息的 SharePoint 列表数据再简单不过了。在 Visual Studio 工具箱中,找到 Mainsoft SharePoint Federator 组中的 SharePointDataSource 控件。将该控件添加到 ClientList.aspx
的设计界面,该文件构成了新 portlet 的默认视图模式。
SharePointDataSource 控件有一个智能标记(右上角的一个小箭头,参见图 5),可以进入 SharePoint 数据源的配置向导。使用向导,自定义将检索到的 SharePoint 数据。向导的第一页包含连接字符串参数。您可以选择在运行时和设计时指定不同的身份验证方案,如果您正在使用 WebSphere Credential Vault,则需要这样做,因为它在 Visual Studio 中不可用。通常,您可以使用受信任的连接(使用您的 Windows 用户凭据)或 WebSphere Portal Credential Vault 进行身份验证,并指定资源名称。
与开箱即用的受信任连接相比,Credential Vault 身份验证需要更多的代码。Credential Vault 身份验证有两种方式:用户和管理员。站点管理员可以添加一个包含有效 SharePoint 登录信息的共享管理员凭据槽,该槽可供所有 WebSphere Portal 用户使用。专用凭据槽由每个用户定义并为其服务。我在示例应用程序中使用的是专用凭据库。
我在新的数据源对话框(参见图 6)中填入 SharePoint URL 和专用 Credential Vault 的资源名称(此处命名为“SharePointAccess”)。
向导的第二页是指定您要显示的 SharePoint 列表。接下来,您可以使用向导中的标准 CAML 查询语法自定义选择结果。在这里,我使用了一个自定义查询,因为我只想返回美国客户。在向导的第五页,我使用可视化查询设计器定义了图 7 中的查询。
您可以使用可视化设计器构建非常复杂的查询,如果您想对其进行微调,可以使用支持 IntelliSense 的 XML 编辑器。稍后,您可以使用控件的属性修改 SharePoint 连接的任何方面。
现在,我需要一种方法来显示 SharePointDataSource 中获取的数据。我选择使用标准的 ASP.NET DataList Web 控件,我将它连接到 SharePoint 数据源的方式与连接到任何其他标准的 .NET 数据源相同。
DataList 控件与更常见的 GridView 控件之间的一个区别是,DataList 默认不会显示任何列(GridView 会显示数据源的所有列)。使用 DataList 的“编辑模板”命令,我选择数据行。在这里,我将以“<全名> 在 <公司>”的格式呈现我们 SharePoint 列表中的每个客户的姓名和公司。这通过向 DataList 的 ItemTemplate 添加一个 Label 控件来实现。在 Label 的 DataBindings 属性中,我使用自定义绑定和以下代码表达式
Eval("FullName") + " at " + Eval("Company")
Eval() 方法以 SharePoint 数据源列的名称作为参数,并返回当前行的值。
我还添加了两个隐藏的标签,将用于将数据发送到其他 portlet。一个包含客户的当前地址,另一个包含电子邮件地址。当需要使用这些字段时,我会回来处理它们。我还向 ItemTemplate 添加了一个 ImageButton,它将确保用户可以选择列表中的项目。ItemTemplate 中的任何命令类型按钮控件(Button、LinkButton 或 ImageButton)都可以实现选择。
现在,让我们让最终用户更容易在第一次访问时将他们的 SharePoint 凭据注册到 WebSphere 的 Credential Vault 中。尽管门户用户可以通过管理界面添加专用的 Credential Vault 槽,但通过 portlet 的“编辑”模式提示他们输入 SharePoint 用户名和密码要用户友好得多。通过打开 WEB-INF\portlet.xml
文件,将“编辑模式”添加到 portlet,该文件使用 Mainsoft 的 Portlet Designer 显示项目 portlet 的属性(参见图 8)。在这里,您可以完全配置 portlet,而无需学习 JSR 168 portlet 规范。
在 Portlet Designer 中,单击“Portlet Modes”中的“...
”按钮,启用编辑模式,并指定一个与编辑模式关联的新 .aspx
文件名。此时,新的 ASPX 文件会自动生成。
我将 SaveCredentials Web 控件(来自 Mainsoft SharePoint Federator 控件组)添加到新表单(参见图 9)。
在控件的属性中,我将 ResourceName 设置为“SharePointAccess”,这与我配置 SharePointDataSource 在运行时检索数据所使用的资源名称相同。
首次访问 portlet 的用户会遇到一个问题:当他们加载视图模式(这是默认模式)时,将没有设置用户凭据,并且会抛出一个 SharePointDataSource 异常。我需要捕获此异常,并告知用户在使用 portlet 之前,必须先在编辑模式(在浏览器中称为“个性化”)中设置 SharePoint 凭据。一种方法是重写 Page_Error() 方法并显示一条信息性消息。使用此技术,我将以下实现添加到 ClientList.aspx
中,其中包含 portlet 的视图模式代码
public void Page_Error(object sender, EventArgs e)
{
Exception ex = Context.Error.GetBaseException();
if (ex is UnauthorizedAccessException || ex.Message.Contains("Unauthorized"))
{
Context.ClearError();
Context.Response.Write("<b>SharePoint authentication
failed.</b><br />Please add your SharePoint login information in the
portlet's personalize mode to access the client list.");
Context.Response.End();
}
}
第一轮开发就到此为止。此时运行该应用程序,在输入 SharePoint 凭据后,将显示以下 portlet(参见图 10)
这是来自 SharePoint 服务器的实际数据,在单点登录环境中聚合到 WebSphere Portal 中。所有这些都只需几个简单的步骤即可完成,只手动添加了几行错误处理代码!
到目前为止还不错。现在是时候通过添加 IPC 支持来让事情更有趣了,IPC 支持使 portlet 之间能够通信。为了使客户列表 portlet 能够传输所选项目的信息,我需要进行以下修改:
- 在 Web Services Description Language (WSDL) 文件中指定传输数据的类型和其他元信息。
- 将 portlet 映射到 WSDL 文件。
- 启用 ProcessAction 属性。
- 为 DataListItems 的 ImageButton 添加 PostBackUrl 属性的参数。
- 处理 DataList 的 ItemCommand 事件以通过 IPC 传输实际值。
考虑到我们的两个目标 portlet 将使用 wpPerson Web 控件渲染地图并显示联系人信息,我为 portlet 指定了两个输出参数。以下是 WSDL 文件中的两个片段,我已将其添加到项目中
[…]
<types>
<xsd:schema targetNamespace="http://www.ibm.com/wps/p2psample3">
<xsd:simpleType name="AddressType">
<xsd:restriction base="xsd:string">
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
</types>
[…]
<binding
name="GoogleMapSearchBinding"
type="tns:GoogleMapSearch_Service">
<portlet:binding/>
<operation name="ClientDetails">
<portlet:action name="ClientDetailsAction"
type="standard"
caption="ClientDetails.action"
description="Get the details of the selected client"
actionNameParameter="ClientDetailsActionParam"/>
<output>
<portlet:param name="ClientDetailsText"
partname="ClientDetails_Text"
boundTo="request-attribute"
caption="ClientDetails.text"/>
</output>
</operation>
</binding>
深入研究 WSDL 的细节超出了本文的范围。Mainsoft 的 Developer Zone 有一篇关于 IPC 的入门文章,名为 “使用 Mainsoft Portal Edition 开发协作 Portlet”。现在您只需要知道“types”元素指定了字符串数据类型,并且 portlet 之间通信的数据在发送端和接收端必须使用相同的数据类型。此数据类型用于绑定 LawFirmClient portlet 的两个输出参数,一个是选定项目的公司地址(“WorkAddressActionParam”),另一个是姓名和电子邮件地址(“ClientDetailsActionParam”),它们用分号分隔。WSDL 文件的完整内容可在项目源代码的下载中找到。
我使用 Portlet Designer 将 WSDL 文件连接到 portlet。Preferences 集合中的一个新键值对告诉 WebSphere Portal 进行关联(参见图 11)。
在 Portlet Designer 中,我启用了 Process Action 属性。这将导致 portlet 对 Web 服务器的所有回发都使用 ProcessAction 阶段,在该阶段处理 IPC 消息。
为了使客户列表 portlet 能够向其他 portlet 发送信息,需要处理用户选择 DataListItem 时触发的事件。由于所有底层的 IPC 基础结构都已就绪,我只需要添加几行代码来设置适当的 IPC 参数的正确值。我向 DataList 的 ItemCommand 事件添加了一个处理程序,当项目选择更改时会触发该事件
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
string name = ((Label)e.Item.FindControl("NameLabel")).Text;
string address = ((Label)e.Item.FindControl("HiddenAddress")).Text;
string email = ((Label)e.Item.FindControl("HiddenEmail")).Text;
Client client = new Client(name, address, email);
PortletRequest.setAttribute("ClientDetailsText", client.ToString());
}
事件的实现将选定客户的姓名、公司地址和电子邮件地址作为字符串插入到 PortletRequest 属性中。PortletRequest 对象用于在 portlet 之间传递 IPC 数据。我使用一个辅助类(Client)来从客户详细信息构建字符串。
为了启用 IPC 操作参数,我需要添加一个输入字段,我将其设为隐藏。输入字段包含 WSDL 操作元素的名称和 actionNameParameter,如下所示:
<input type="hidden" name="ClientDetailsActionParam" value="ClientDetailsAction" />
我现在已经使 portlet 具备了向其他 portlet 发送 IPC 数据的功能。
接下来,我将添加两个额外的 portlet,让它们接收和解析由客户列表 portlet 发送的数据,并渲染它们自己的表示。
Portlet Designer 用于在我们的门户应用程序中创建和配置两个额外的 portlet。Add Portlet 按钮会创建一个新的 portlet。我通过在 Portlet Modes 属性中设置视图模式,让每个 portlet 的视图模式由两个新的 aspx 页面实现(参见图 12)。
Google Maps portlet 将使用 Google JavaScript API 在 portlet 中渲染客户的位置。为了将 Google Maps 服务嵌入到 portlet 中,您需要注册一个 Google Maps API 密钥。此密钥将在 portlet 的 JavaScript 代码中用于初始化 API 访问。尽管可下载的 LawFirmClient 应用程序包含一个 Google Maps API 密钥,但我建议您申请自己的密钥并使用它。
一个极简的 HTML 设计足以实现地图 portlet。一个带有“map”ID 的 div 标签是 Google Maps API 用于渲染请求地图的占位符。我需要处理从客户列表 portlet 发送的 IPC 数据,并将其作为 JavaScript 函数参数重新发送到 Google Maps API。
第一步是为地图 portlet 添加一个 WSDL 文件,该文件包含与客户列表 WSDL 文件相同的 datatype。主要区别在于,此文件定义了输入元素而不是输出元素。第二,我使用 Portlet Designer 在 WSDL 文件和 portlet 之间创建新的映射,如前所述。第三,我添加了检索和处理参数值的逻辑。此步骤已添加到地图 portlet 的类中,如下所示:
public partial class GoogleMaps : Mainsoft.Web.Portal.Page
{
protected string searchAddress = "";
protected void Page_Load(object sender, EventArgs e)
{
SetRenderParameter("RenderClientDetailsText", Request.Params["ClientDetailsText"]);
}
}
PageLoad()
会在包含 IPC 数据的回调中调用两次,这些回调针对 ProcessAction
属性设置为 True 的 portlet。第一次调用包含 IPC 数据作为 HTTPRequest
参数,而第二次调用是标准的 PageLoad()
调用。为了区分两次调用的逻辑,您可以使用 IsInProcessAction
,这是从 Mainsoft.Web.Portal.Page
继承的一个属性。对于 IPC 调用,IsInProcessAction
为 true,对于标准调用为 false。在上面的源代码中,成员变量 SearchAddress
用于存储从 HTTPRequest 参数“GoogleMapSearchText”(名称在 WSDL 文件中定义)中检索到的地址。然后,使用我插入到标记中的以下代码(仅在渲染阶段执行),将此值注入到与 Google Maps API 通信的 JavaScript 代码中。它还将输入字段设置为显示 portlet 中的实际地址文本。
<% string clientData = (string)Request.Params["RenderClientDetailsText"]; if (!String.IsNullOrEmpty(clientData)) { String[] properties = clientData.Split(';'); if (properties.Length == 3) this.searchAddress = properties[(int)LawFirmClients.eClientDetails.Address]; } %>
对于 ClientDetails portlet,它将用于启用通信,我使用了 Mainsoft 的 wpPerson Web 控件(参见图 13)。wpPerson 控件提供与命名人员相关的上下文协作功能,其语法和行为类似于 WebSphere Portal 的 person 标签。它会显示门户用户的在线状态,同时考虑门户环境中已安装和启用的 Domino 和扩展产品及服务器。
ClientDetails portlet 的配置遵循与地图 portlet 相同的步骤。我添加了一个 WSDL 文件,该文件定义了 IPC 输入绑定,使用 Portlet Designer 将其连接到 portlet,然后添加逻辑。您是否还记得客户列表 portlet 中的两个隐藏标签包含所选用户的公司地址和电子邮件地址?这些数据以及客户的全名,就是通过 IPC 发送的数据。我对数据进行字符串编码,然后在接收端,解码字符串,并使用与目标 portlet 相关联的字段。下面的代码展示了 ClientDetails portlet 如何解码 IPC 字符串并使用数据来设置控件的属性。第一部分来自代码隐藏,第二段代码插入到标记中
protected void Page_Load(object sender, EventArgs e)
{
SetRenderParameter("RenderClientDetailsText", Request.Params["ClientDetailsText"]);
}
<%
string clientData = (String)Request.Params["RenderClientDetailsText"];
if (!String.IsNullOrEmpty(clientData))
{
String[] properties = clientData.Split(';');
if (properties.Length == 3)
{
WpPerson1.DisplayName = properties[(int)LawFirmClients.eClientDetails.Name];
WpPerson1.Value = properties[(int)LawFirmClients.eClientDetails.Email];
}
}
%>
实施现在已准备好供最终用户使用。重要的是要注意,一旦应用程序部署完成,门户用户就需要自己激活连接。这可以通过使用 Portlet Wiring Tool(参见图 14)来完成,该工具可以从 WebSphere Portal Server 的“编辑页面布局”下的“Wires”选项卡访问。
在添加两个连接(一个从客户列表到地图;另一个从客户列表到客户详细信息)后,我们就可以开始了。图 15 显示了运行我们应用程序的 WebSphere Portal 的屏幕截图,其中包含 SharePoint 内容、Google Maps 数据以及 WebSphere Portal 的人员启用通信功能。
结论
感谢您阅读本教程!LawFirmClient 项目的完整源代码可以从本页面左侧菜单下载。欢迎您下载 Mainsoft, Portal Edition 的评估版,其中包含 SharePoint 集成功能,亲自体验一下如何将 SharePoint 数据与企业 Java 应用程序集成,而无需依赖复杂的互操作性层或外部开发团队。