在Silverlight被引入到SharePoint开发中后,很多时候SL需要调用SP后台的service来达到数据交互的目的,我们当然可以在iis上部署另一套专门通过SharePoint 的object model 来完成数据交互的service, Silverlight客户端只要调用这个service即可,但是这样的service脱离的SharePoint的context,我们无法通过SPContext对象来直接取得相关信息,并且单独维护一个service站点,无形中也增加了复杂性。
此处详细介绍如何配置一个可供Silverlight调用的SharePoint 内置web service.
首先,需要创建一个Web service
1.打开visual studio 2008,新建一个ASP.NET Web service application 的项目InbuildCustomizationService
2.在生成的CustomizationService.asmx.cs文件中完成你的代码。
3. 为你的项目的dll添加强命名,如果你的web service中引入了其他的Assembly, 将这些Assembly分别强命名。
4. 将所有的Assembly加入到GAC中:
在VS 2008的命令窗口 输入 gacutil.exe -if "<Full file system path to DLL>"
.
5. 通过Refactor等反编译软件取得CustomizationService.dll的信息,打开CustomizationService.asmx,将其内容修改为
其中红色部分内容来自Refactor, InbuildCustomizationService.CustomizationService是class名,InbuildCustomizationService是Assembly名。
6.Copy CustomizationService.asmx到"\\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS",此路径映射SharePoint站点的http//site/_layouts/, 在VS 2008的命令窗口 输入
disco http://MyServer/_layouts/CustomizationService.asmx
将生成的CustomizationService.disco 和CustomizationService.wsdl文件Copy到 "\\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS."
7.加入SharePoint的一些类引用,即CustomizationService.disco和CustomizationService.wsdl中的<?xml version="1.0" encoding="utf-8"?>替换为
<% @ Assembly Name = " Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c " %>
<% @ Import Namespace = " Microsoft.SharePoint.Utilities " %>
<% @ Import Namespace = " Microsoft.SharePoint " %>
<% Response.ContentType = " text/xml " ; %>
8.修改CustomizationService.disco ,将其中的Contract ref和soap替换为动态的URL
< soap address = " <% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %> " xmlns:q1 = " http://tempuri.org/ " binding = " q1:CustomizationServiceSoap " xmlns = " http://schemas.xmlsoap.org/disco/soap/ " />
< soap address = " <% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %> " xmlns:q2 = " http://tempuri.org/ " binding = " q2:CustomizationServiceSoap12 " xmlns = " http://schemas.xmlsoap.org/disco/soap/ " />
9.修改CustomizationService.wsdl,将其中的soap address替换为动态的URL
10. 将CustomizationService.wsdl和CustomizationService.disco重命名为.aspx,例如CustomizationServicewsdl.aspx. 因为layout下sharepoint无法识别到.wsdl或.disco文件类型。
完成上述操作,你已经可以在http://yoursite/_layouts/CustomizationService.asmx下调用Web Service了,但是笔者发现,这样的webservice在被silverlight的客户端调用时依旧无法得到SPContext的对象,在CustomizationService.asmx中使用的SPContext返回null值,因此只能改变发布的位置,象SharePoint内置的访问list的web service-list.asmx一样,将CustomizationService.asmx部署到http://yoursite/_vti_bin/下。
11. Copy CustomizationService.asmx,CustomizationServicewsdl.aspx,CustomizationServicedisco.aspx 三个文件到"\program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI" 下,修改ISAPI目录下的spdisco.aspx 文件,在其中加入
< discoveryRef ref =<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + " /_vti_bin/CustomizationService.asmx?disco " ),Response.Output); %> xmlns = " http://schemas.xmlsoap.org/disco/ " />
这样你在客户端调用是,可以直接用vs添加这个webservice作为web reference
完成以上内容,重启iis,然后打开"http://yoursite/_vti_bin/CustomizationService.asmx"可以访问我们部署的Service。同时SPContext对象对应了当前的Context。
12. 添加一个Silverlight application, 添加http://yoursite/_vti_bin/CustomizationService.asmx作为web reference,当异步访问Service时出错。检查发现Silverlight存在跨域访问的问题,创建跨域访问协议文件clientaccesspolicy.xml,内容如下,将其Copy到yoursite在iis上的根目录下,类似"C:\Inetpub\wwwroot\wss\VirtualDirectories\yoursite”下。
< access - policy >
< cross - domain - access >
< policy >
< allow - from http - request - headers = " * " >
< domain uri = " * " />
</ allow - from >
< grant - to >
< resource include - subpaths = " true " path = " / " />
</ grant - to >
</ policy >
</ cross - domain - access >
</ access - policy >
完成上述操作,可以发现我们开发的Silverlight client可以通过一个自定义的in-build SharePoint service安全的访问SharePoint数据了
加一张Demo结果图: