前言
最近的一个项目需要在MOSS 2007中嵌入Silverlight报表,而Silverlight报表则需要开发相应的WebService作为数据源,而这个从MOSS列表中获取数据的Web Service则要以自定义WebService的方法部署在MOSS站点中。园子里几位前辈在若干年前已经写过一些在MOSS中部署自定义WebService的方法(如:文章一,文章二),但可能是MOSS版本不同的缘故,我试过数次都未能成功,最终摸索出了worked solution(与前面两位前辈文章中描述的solutions不同点很多),特总结于此,希望能够帮助需要的朋友们。
开发WebService
开发WebService的过程与平时相仿,新建WebService项目并直接在code-behind中完成相关代码即可,编译后生成Ceair.Union.Web.dll,如下例:
为WebService进行强命名
在WebService项目上“右键”→“属性”中选择“签名”选项卡,勾选“为程序集签名”选项,并在下方的下拉列表中新建一个snk文件,密码可以为空,过程如下图所示:
生成wsdl和dicso文件
这时候,按理说我们可以在VS中直接选择在浏览器中打开,查看刚刚写好的WebService,如下图:
接下来,我们可以用两种方法来获取这个Service的wsdl文件和disco文件:
A方法:
用VisualStudio的命令行工具执行:
disco http:
//
localhost:
6949
/
B2EWidgetService.asmx
然后就可以在VisualStudio的根目录下找到生成的B2EWidgetService.wsdl和B2EWidgetService.disco文件。
B方法:
直接在浏览器里输入:
http:
//
localhost:
6949
/
B2EWidgetService.asmx
?
wsdl
http:
//
localhost:
6949
/
B2EWidgetService.asmx
?
disco
并将结果保存为B2EWidgetService.wsdl和B2EWidgetService.disco文件即可。
修改wsdl和disco文件
我们知道wsdl文档和disco文件都是以XML格式对WebService进行描述的,一般情况下可以直接访问到(上节B方法)。而在MOSS中的WebService(包括moss自带的一些,如lists.asmx、alerts.asmx等)其wsdl和disco文件要通过ASP.NET程序化的方式来动态生成并输出。
在这里,我们的自定义WebService也要仿照“C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI”里MOSS自带WebService的方法进行部署,步骤如下:
步骤一
分别将B2EWidgetService.wsdl和B2EWidgetService.disco重命名为B2EWidgetServicewsdl.aspx和B2EWidgetServicedisco.aspx。
步骤二
打开B2EWidgetServicedisco.aspx,将里面的代码(注意高亮部分的代码是下面需要改动的,斜体部分为此例子中特定的):
代码
<?
xml version="1.0" encoding="utf-8"
?>
<
discovery
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd
="http://www.w3.org/2001/XMLSchema"
xmlns
="http://schemas.xmlsoap.org/disco/"
>
<
contractRef
ref
="
http://localhost:6949/B2EWidgetService.asmx?wsdl"
docRef
="
http://localhost:6949/B2EWidgetService.asmx"
xmlns
="http://schemas.xmlsoap.org/disco/scl/"
/>
<
soap
address
="
http://localhost:6949/B2EWidgetService.asmx"
xmlns:q1
="http://sharepoint.microsoft.com/samples/"
binding
="q1:
B2EWidgetServiceSoap"
xmlns
="http://schemas.xmlsoap.org/disco/soap/"
/>
<
soap
address
="http://localhost:6949/B2EWidgetService.asmx"
xmlns:q2
="http://sharepoint.microsoft.com/samples/"
binding
="q2:B2EWidgetServiceSoap12"
xmlns
="http://schemas.xmlsoap.org/disco/soap/"
/>
</
discovery
>
修改为如下所示:
<%
@ Page Language
=
"
C#
"
Inherits
=
"
System.Web.UI.Page
"
%>
<%
@ Assembly Name
=
"
Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
"
%>
<%
@ Import Namespace
=
"
Microsoft.SharePoint.Utilities
"
%>
<%
@ Import Namespace
=
"
Microsoft.SharePoint
"
%>
<%
Response.ContentType
=
"
text/xml
"
;
%>
<
discovery
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd
="http://www.w3.org/2001/XMLSchema"
xmlns
="http://schemas.xmlsoap.org/disco/"
>
<
contractRef
ref
=<%
SPEncode.WriteHtmlEncodeWithQuote(Response, SPWeb.OriginalBaseUrl(Request) + "?wsdl", '"'); %
>
docRef=
<%
SPEncode.WriteHtmlEncodeWithQuote(Response, SPWeb.OriginalBaseUrl(Request),
'
"'); %> xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<
soap address
=<
% SPEncode.WriteHtmlEncodeWithQuote(Response, SPWeb.OriginalBaseUrl(Request),
'
"'); %> xmlns:q1="http://tempuri.org/" binding="q1:B2EWidgetServiceSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
</
discovery
>
步骤三
打开B2EWidgetServicewsdl.aspx,将里面的代码(注意高亮部分的代码是下面需要改动的,斜体部分为此例子中特定的):
代码
<?
xml version="1.0" encoding="utf-8"
?>
<
wsdl:definitions
xmlns:soap
="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tm
="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:soapenc
="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:mime
="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:tns
="http://sharepoint.microsoft.com/samples/"
xmlns:s
="http://www.w3.org/2001/XMLSchema"
xmlns:soap12
="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:http
="http://schemas.xmlsoap.org/wsdl/http/"
targetnamespace
="http://sharepoint.microsoft.com/samples/"
xmlns:wsdl
="http://schemas.xmlsoap.org/wsdl/"
>
<
wsdl:types
>
<
s:schema
elementformdefault
="qualified"
targetnamespace
="http://sharepoint.microsoft.com/samples/"
>
<
s:element
name
="HelloWorld"
>
<
s:complextype
/>
。。。。。。。
</
wsdl:binding
>
<
wsdl:service
name
="B2EWidgetService"
>
<
wsdl:port
name
="B2EWidgetServiceSoap"
binding
="tns:B2EWidgetServiceSoap"
>
<
soap:address
location
="
http://localhost:6949/B2EWidgetService.asmx"
/>
</
wsdl:port
>
<
wsdl:port
name
="B2EWidgetServiceSoap12"
binding
="tns:B2EWidgetServiceSoap12"
>
<
soap12:address
location
="http://localhost:6949/B2EWidgetService.asmx"
/>
</
wsdl:port
>
</
wsdl:service
>
</
wsdl:definitions
>
修改为:
代码
<%
@ Page Language
=
"
C#
"
Inherits
=
"
System.Web.UI.Page
"
%>
<%
@ Assembly Name
=
"
Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c
"
%>
<%
@ Import Namespace
=
"
Microsoft.SharePoint.Utilities
"
%>
<%
@ Import Namespace
=
"
Microsoft.SharePoint
"
%>
<%
Response.ContentType
=
"
text/xml
"
;
%>
<
wsdl:definitions
xmlns:s
="http://www.w3.org/2001/XMLSchema"
xmlns:soap12
="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:mime
="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:tns
="http://sharepoint.microsoft.com/samples/"
xmlns:soap
="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tm
="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:http
="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soapenc
="http://schemas.xmlsoap.org/soap/encoding/"
targetNamespace
="http://sharepoint.microsoft.com/samples/"
xmlns:wsdl
="http://schemas.xmlsoap.org/wsdl/"
>
<
wsdl:types
>
<
s:schema
elementFormDefault
="qualified"
targetNamespace
="http://sharepoint.microsoft.com/samples/"
>
<
s:element
name
="HelloWorld"
>
<
s:complexType
/>
。。
。。。。。。。
</
wsdl:binding
>
<
wsdl:service
name
="B2EWidgetService"
>
<
wsdl:port
name
="B2EWidgetServiceSoap"
binding
="tns:B2EWidgetServiceSoap"
>
<
soap:address
location
=<%
SPEncode.WriteHtmlEncodeWithQuote(Response,SPWeb.OriginalBaseUrl(Request), '"'); %
>
/>
</
wsdl:port
>
</
wsdl:service
>
</
wsdl:definitions
>
步骤四
打开“C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI”下的"spdisco.aspx"文件,可以看到MOSS自带的WebService都注册于此,我们也需要把自己的自定义WebService加进来(在该文件下面直接附加以下两行):
代码
<
contractRef
ref
=<%
SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/B2EWidgetService.asmx?wsdl"),Response.Output); %
>
docRef=
<
% SPHttpUtility.AddQuote
(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/B2EWidgetService.asmx"),Response.Output); %
>
xmlns="http://schemas.xmlsoap.org/disco/scl/" />
<
discoveryRef
ref
=<%
SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/B2EWidgetService.asmx?disco"),Response.Output); %
>
xmlns="http://schemas.xmlsoap.org/disco/" />
部署WebService
完成上述步骤后将B2EWidgetService.asmx以及B2EWidgetServicewsdl.aspx和B2EWidgetServicedisco.aspx拷贝到“C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI”下,并将WebService编译后的Ceair.Union.Web.dll拷贝到MOSS站点的Bin目录下即可完成部署。
查看结果
完成部署后,即可在MOSS站点的“_vti_bin/”路径下看到刚刚部署的WebService。
注意事项
- 如果WebService代码中访问到的列表数据需要权限,则可使用“SPSecurity.RunWithElevatedPrivileges”进行权限提升,否则只有网站集管理员才能够访问此Service,其他人访问则弹出登录对话框。
- 本文中的解决方案不需将dll注册到GAC,只需放入要使用此Service的MOSS站点的Bin目录下。
- WebService的测试可使用HttpWatch、Firebug等工具