一. 项目描述
使用biztalk2006在vs2005开发环境中做一个简单的测试业务流程,主要是测试使用biztalk发布一个web services,这个web services接受用户发送的请求,然后根据用户要求通过sql adapter到sql server数据库中提取相关数据,最后作为web services的response返回给用户。
业务流程如下:
图中,Port_2是双向接收端口,就是这个端口需要发布为web services,Port_1是一个用sql adapter向导做的双向发送端口,使用的是存储过程,参数只有一个Rows,指示需要获取的数据行数,存储过程返回Rows要求行数的数据。
相应的Schema也很简单:
Biztalk项目做好后,编译,部署,一切顺利。
在biztalk管理器中,在这个应用程序中添加物理发送端口,指向相应的数据库连接,指定返回的Schema类型,绑定了Port_1逻辑端口。
最后用biztalk web services发布向导做Port_2端口的web services的发布设置。按照向导的指示一步步的做,其中有一步需要选择是否将此web services指定给某个应用程序的接收位置,在这里选择作为本应用程序的接收位置,这样就将要生成的web services跟Port_2端口进行了绑定。
在biztalk管理器中启动这个应用程序,启动正常。
二. 问题现象
建立一个winform的应用,引用上面过程中发布的web services,引用后在项目中生成这个web services代理类,拥有一个叫做Operation_1的方法,这个方法就是Port_2端口定义的操作名。
在界面上放置一个button,在这个button的点击事件中,新建一个web services代理类的实例,新建一个Operation_1方法的参数的实例,之后调用Operation_1方法,接收Operation_1方法的返回值。
以上是测试场景,调用Operation_1方法的代码处设置一个断点,调试执行这个winform应用程序,点击button,程序在调用Operation_1方法处遇到断点中断,这时进行单步调试,程序执行调用Operation_1方法,实际就是调用web services的操作,结果返回一个错误:SOAP内部处理失败(SoapException: Internal SOAP Processing Failure)。同时在事件查看器中有以下的错误提示:
l 用户 'NT AUTHORITY\NETWORK SERVICE' 登录失败。
l 试图连接到服务器“JINJZ2003”上的“BizTalkMgmtDb”SQL Server 数据库失败。 错误:“无法打开登录所请求的数据库 "BizTalkMgmtDb"。登录失败。”
(An attempt to connect to "BizTalkMgmtDb" SQL Server database on server "Server" failed with error: "Cannot open database requested in login 'BizTalkMgmtDb'. Login fails.".)
l 消息引擎无法注册接收位置“/BiztalkSqlSP_Proxy/BiztalkSqlSP_Orchestration_1_Port_2.asmx”的“SOAP”的适配器。请验证接收位置存在,且独立的适配器在可以访问 BizTalk 数据库的帐户下运行。
(The Messaging Engine failed to register the adapter for "SOAP" for the receive location "/VirtualDirectory/Name.asmx". Please verify that the receive location is valid, and that the isolated adapter runs under an account that has access to the BizTalk databases.)
三. 解决过程
根据错误提示,到微软的支持网站查询,果然有这个错误的相关说明和处理方法,是因为web services对应的应用程序池的帐户不是BizTalk Isolated Host Users组的成员。 BizTalk Isolated Host Users组具有对'BizTalkMgmtDb'数据库的访问权限。同时这个帐户也必须是IIS_WPG组的成员。
查看了IIS中这个web services对应的应用程序池是DefaultAppPool,DefaultAppPool对应的帐户是网络服务(network service),在IIS_WPG组中有network service帐户,可是在BizTalk Isolated Host Users组中没有network service帐户,于是在BizTalk Isolated Host Users组中加入network service帐户。测试,故障依旧,在事件查看器中依然有错误提示:network service无法登录'BizTalkMgmtDb'数据库。真是有点奇怪。
将DefaultAppPool对应的帐户改为“IWAM_机器名”,同时也把“IWAM_机器名”加入到BizTalk Isolated Host Users组和在IIS_WPG组,然后重新启动IIS,再进行测试。依然有错误,不过这次错误提示不是原来的“SoapException: Internal SOAP Processing Failure”,改成了“System.Web.Services.Protocols.SoapException: 服务器无法处理请求。 ---> System.InvalidOperationException: 无法生成临时类(result=1)。\nerror CS2001: 未能找到源文件“C:\\WINDOWS\\TEMP\\zyobqxbr.0.cs()”
看来数据库访问权限的问题解决了,查看事件查看器也没有了数据访问的错误记录。就新产生的错误去查微软支持网站,找到相关内容,说web services对应的应用程序池的帐户需要对%systemroot%\Temp文件夹有读写权限,因为Web service (.asmx)文件的JIT会在%systemroot%\Temp文件夹编译生成DLL文件,如果应用程序池的帐户没有%systemroot%\Temp文件夹的读写权,就不能生成相关的dll文件。
按此说明,设置给“IWAM_机器名”帐户读写%systemroot%\Temp文件夹的读写权,再测试,OK,成功,Operation_1方法成功的返回的预期的结果。
参考文档:
1. BizTalk Server 2004 和 Web 服务:http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/BTS2004WP5cab05ab.mspx?mfr=true
2. You cannot call an orchestration that is exposed as a Web service on a server that is running BizTalk Server 2004:http://support.microsoft.com/?kbid=910295