在 SharePoint Foundation 中创建自定义 WCF 服务
上次修改时间: 2011年2月7日
适用范围: SharePoint Foundation 2010
这一部分演练说明如何创建自定义 Windows Communication Foundation (WCF) 服务,以便使用户可以将列表项还原为其以前版本。列表项的版本历史记录不会通过其他客户端 API 公开,因此,此示例将创建一个使用服务器端对象模型的服务,以便向客户端应用程序提供此功能。
此示例说明如何在 Microsoft Visual Studio 2010 中创建一个自定义 WCF 服务作为您可部署到任何服务器场的 Microsoft SharePoint Foundation 项目。此外,由于 SharePoint Foundation 项目类型默认情况下不支持 WCF 库,因此,此示例将涉及创建一个 WCF 服务库作为外部项目,以便为您的项目生成 IService1 和 Service1 .cs 或 .vb 文件。
此示例假定您已完成本演练的前两部分,即实现 SharePoint Foundation REST 接口和实现客户端对象模型,并且已创建用于实现自定义 WCF 服务的 Windows 窗体应用程序。
创建 WCF 服务以将列表项还原为以前版本
若要为 WCF 服务创建 SharePoint Foundation 项目,请在 Visual Studio 中打开 ProjectTracker 解决方案。在"解决方案资源管理器"中,右键单击该解决方案。在"文件"菜单上,指向"添加",然后单击"新建项"。在"添加新项"对话框的"已安装的模板"选项卡中,展开"Visual Basic"或"Visual C#"节点,选择"SharePoint",再选择"空白 SharePoint 项目",然后键入 RevertService 作为项目名称。单击"确定"。
在"SharePoint 自定义向导"中,确认指定了正确的本地网站进行调试。由于沙盒解决方案不支持 WCF 服务,因此请选择"部署为场解决方案",然后单击"完成"。
若要创建外部 WCF 项目以便获取其 IService1 和 Service1 .cs 或 .vb 文件,请再次单击 ProjectTracker 解决方案,并按照步骤 1 的相同过程打开"添加新项目"对话框。展开"Visual Basic"或"Visual C#"节点,依次选择"WCF"和"WCF 服务库",键入 WcfService 作为名称,然后单击"确定"。
将生成的 IService1 和 Service1 文件复制到 RevertService 项目中。因为您不再需要 WCF 服务库项目,所以您可以通过右键单击"WCF 服务库"并单击"删除",从解决方案中删除它。
在 RevertService 项目中添加对 System.Runtime.Serialization 和 System.ServiceModel WCF 程序集以及对服务器对象模型的主程序集 Microsoft.SharePoint 的引用。右键单击"RevertService"项目,单击"添加引用",然后在".NET"选项卡上选择每个这些程序集。
若要添加对包含 SharePoint Foundation 提供的服务工厂的 Microsoft.SharePoint.Client.ServerRuntime 的引用,请使用"添加引用"框的"浏览"选项卡导航至 %Windows%\assembly\GAC_MSIL\Microsoft.SharePoint.Client.ServerRuntime 内的 Microsoft.SharePoint.Client.ServerRuntime.dll 文件,选择该 DLL,然后单击"确定"。
在 IService1.cs(或 IService1.vb)中指定自定义 WCF 服务的约定,将自动生成的服务约定替换为以下接口定义,其中 Revert 方法接受要还原其中更改的列表的名称和要还原的项的 ID:
Imports System.Runtime.Serialization Imports System.ServiceModel Namespace WcfService <ServiceContract()> _ Public Interface IRevert <OperationContract()> _ Sub Revert(ByVal listName As String, ByVal listItemId As Integer) End Interface End Namespace
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace WcfService { [ServiceContract] public interface IRevert { [OperationContract] void Revert(string listName, int listItemId); } }
通过将 Service1.cs (Service1.vb) 的自动生成代码替换为以下代码,指定服务的实现。此示例使用 SharePoint Foundation 对象模型按名称检索列表,按 ID 检索要还原的项,检查各个项版本是否存在并按一种版本还原它们:
Imports Microsoft.SharePoint.Client.Services Imports System.ServiceModel.Activation Namespace WcfService <BasicHttpBindingServiceMetadataExchangeEndpointAttribute()> _ <AspNetCompatibilityRequirements(RequirementsMode := AspNetCompatibilityRequirementsMode.Required)> _ Public Class RevertService Implements IRevert Public Sub Revert(ByVal listName As String, ByVal listItemId As Integer) Implements IRevert.Revert Dim oList As SPList = SPContext.Current.Web.Lists(listName) Dim oItem As SPListItem = oList.GetItemById(listItemId) If oItem.Versions.Count > 1 Then oItem.Versions.Restore(1) End If End Sub End Class End Namespace
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace WcfService { using Microsoft.SharePoint.Client.Services; using System.ServiceModel.Activation; using Microsoft.SharePoint; [BasicHttpBindingServiceMetadataExchangeEndpointAttribute] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] public class RevertService : IRevert { public void Revert(string listName, int listItemId) { SPList oList = SPContext.Current.Web.Lists[listName]; SPListItem oItem = oList.GetItemById(listItemId); if (oItem.Versions.Count > 1) { oItem.Versions.Restore(1); } } } }
在上面的示例中,RevertService 类具有一个用于绑定的属性 BasicHttpBindingServiceMetadataExchangeEndpointAttribute,此属性指示 SharePoint Foundation 服务工厂自动为服务创建元数据交换终结点。
现在,服务的实现已经就绪,您可以将服务部署到 SharePoint Foundation。右键单击"RevertService"项目,指向"添加"并单击"SharePoint 映射文件夹"。在"添加 SharePoint 映射文件夹"对话框中,选择"ISAPI",然后单击"确定"以将 SharePoint Foundation 配置单元的 ISAPI 文件夹映射到 RevertService 项目。如果 Visual Studio 在 RevertService 项目的 ISAPI 文件夹中创建了 RevertService 子文件夹,请右键单击该子文件夹并单击"删除"将其删除。
若要在 ISAPI 文件夹中为您的服务创建一个注册文件,请单击项目中的 ISAPI 文件夹,在"项目"菜单上,单击"添加新项"。在"已安装的模板"下,选择"常规"。选择"文本文件",将此文件命名为 Revert.svc,然后单击"添加"。
将下面的服务声明添加到 Revert.svc 中,此类服务声明指定 SharePoint Foundation 工厂和包含这些工厂的命名空间。在此示例中,MultipleBaseAddressBasicHttpBindingServiceHostFactory 为 SOAP 类型的 Web 服务指定服务工厂。服务类声明还指定服务类的名称,并使用标记指定程序集的强名称。
<%@ServiceHost Language="C#" Debug="true" Service="WcfService.RevertService, $SharePoint.Project.AssemblyFullName$" Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
如果您正在 Visual Basic 中创建服务,请指定 VB 而不是 C# 作为语言,并在 Service 属性中包括在步骤 1 中指定的 SharePoint Foundation 项目的名称,如下所示:
<%@ServiceHost Language="VB" Debug="true" Service="RevertService.WcfService.RevertService, $SharePoint.Project.AssemblyFullName$" Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
由于 Visual Studio 2010 默认情况下不会处理以前的 .svc 文件中使用的标记类型,因此您必须在项目文件中添加其他指令。保存您的项目中的所有更改,右键单击"RevertService"项目并单击"卸载项目"。再次右键单击"RevertService"节点,单击"编辑 RevertService.csproj"或"编辑 RevertService.vbproj",然后将如下所示的 <TokenReplacementFileExtensions> 标记添加到 .csproj 或 .vbproj 文件中的第一个属性组,以便能够处理 .svc 文件类型中的标记。
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="https://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{F455078E-8836-403A-9E63-5E5F21B5F694}</ProjectGuid> <OutputType>Library</OutputType> <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>RevertService</RootNamespace> <AssemblyName>RevertService</AssemblyName> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> <ProjectTypeGuids>{BB1F664B-9266-4fd6-B973-E1E44974B511};{14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <SandboxedSolution>False</SandboxedSolution> <TokenReplacementFileExtensions>svc</TokenReplacementFileExtensions> </PropertyGroup> . . . .
在添加上面的标记之后,保存项目并关闭 .csproj 文件。在"解决方案资源管理器"中,右键单击"RevertService"项目,并单击"重新加载项目"。
若要将自定义 Web 服务部署到 SharePoint Foundation,请在"解决方案资源管理器"中右键单击"RevertService"项目并单击"部署"。Visual Studio 将编译项目的节点,生成 WSP 文件并将该文件部署到前端 Web 服务器。
若要从 ProjectTracker 客户端应用程序中使用自定义 Web 服务,请在"解决方案资源管理器"中右键单击应用程序的"服务引用"节点,单击"添加服务引用"。在"添加服务引用"对话框中,在"地址"框中键入自定义 WCF 服务的 URL,并指定 MEX 作为元数据交换终结点的标准名称,如下所示:https://Server/sites/SiteCollection/MyWebSite/_vti_bin/Revert.svc。单击"转到"以下载服务信息,然后单击"确定"以添加引用。
若要在实现自定义服务的 Form1 中添加一个"Revert"(还原)按钮,请右键单击"Save"(保存)按钮旁边的窗体标题栏,并在打开的下拉列表中选择"Button"。
在按钮的"属性"窗口中,将"DisplayStyle"设置为"Text",并键入 Revert(还原)作为"Text"设置的值。
双击"Revert"(还原)按钮,并为其 Click 事件添加以下调用自定义 WCF 服务的标准 WCF 代理设置代码。解析对程序集的引用,方法是右键单击代码中带红色下划线的元素,指向"解析",并接受为 System.ServiceModel 命名空间和自定义 WCF 服务的命名空间 (ProjectTracker.ServiceReference2) 建议的程序集引用。
Private Sub toolStripButton2_Click(ByVal sender As Object, ByVal e As EventArgs) ' Set up proxy. Dim binding As New BasicHttpBinding() binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm Dim endpoint As New EndpointAddress(websiteUrl + "/_vti_bin/Revert.svc") Dim proxy As New RevertClient(binding, endpoint) proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation ' Call web service. proxy.Revert("Projects", DirectCast(projectsBindingSource.Current, ProjectsItem).Id) ' Refresh the UI. context.MergeOption = System.Data.Services.Client.MergeOption.OverwriteChanges context.Projects.ToList() projectsBindingSource.ResetCurrentItem() End Sub
private void toolStripButton2_Click(object sender, EventArgs e) { // Set up proxy. BasicHttpBinding binding = new BasicHttpBinding(); binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm; EndpointAddress endpoint = new EndpointAddress(websiteUrl + "/_vti_bin/Revert.svc"); RevertClient proxy = new RevertClient(binding, endpoint); proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; // Call web service. proxy.Revert("Projects", ((ProjectsItem)projectsBindingSource.Current).Id); // Refresh the UI. context.MergeOption = System.Data.Services.Client.MergeOption.OverwriteChanges; context.Projects.ToList(); projectsBindingSource.ResetCurrentItem(); }
请注意,在前面示例的 Revert 方法调用中,指定了 SharePoint Foundation 列表的名称,并且使用 Current 属性返回 Projects DataGridView 控件中的当前选定项的 ID。在调用 Web 服务之后,代码将刷新用户界面 (UI) 并从 SharePoint Foundation 中重新检索数据。
按 F5 运行客户端应用程序,通过更改 Projects DataGridView 中的某一项并单击"Revert"(还原)按钮来测试 Web 服务。
有关完整的 Form1 代码示例,请参阅 填写 SharePoint Foundation WCF 表单 1 示例。
请参阅
概念
演练:在 SharePoint Foundation 中创建和实现自定义 WCF 服务
SharePoint Foundation 2010 中的 WCF 服务