13719654321 发表于 2015-9-29 10:11:11

如何创建可供Silverlight调用的SharePoint in-build web service

  在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,将其内容修改为


<%@ WebService Language="C#"Class="InbuildCustomizationService.CustomizationService, InbuildCustomizationService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30d08361d816be91" %>  
  其中红色部分内容来自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"?>替换为

代码

<%@ Page Language="C#" Inherits="System.Web.UI.Page" %>
<%@ 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

代码

<contractRef ref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request) + "?wsdl"),Response.Output); %> docRef=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output);%> xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<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
  


<soap:address location=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %> />  
  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 文件,在其中加入

代码

<contractRefref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/CustomizationService.asmx?wsdl"),Response.Output); %> docRef=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/CustomizationService.asmx"),Response.Output); %> xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<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”下。

代码

<?xml version="1.0" encoding="utf-8" ?>
<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结果图:
页: [1]
查看完整版本: 如何创建可供Silverlight调用的SharePoint in-build web service