Silverlight跨域调用gSoap/Java web service 以及wsdl文件的修改
Posted on 2012-01-11 03:37 MonkChen 阅读(1873) 评论(3) 收藏 举报应用场景: silverlight客户端 调用gSoap编写的web service,遇到两个问题
1)Silverlight跨域调用web service的安全限制
2)vs2010添加gSoap web service,wsdl解析遇到问题,无法生成代理类代码
经过干小时摸索,解决问题,好记性不如烂笔头,特此记下以备忘。
解决方案:
- 查了众多资料,都说要把ServiceReferences.ClientConfig文件复制到IIS的根目录或者网站的根目录,进一步研究发现是要放在web service端的目录下,而不是客户端。可是我的gSoap服务宿主是控制台程序,起初放到去无任何效果,依然无法调用。
后来发现ie地址栏输入http://localhost:8090/ServiceReferences.ClientConfig显示的依然是wsdl代码,客户端无法获取该配置文件导致的。于是猛然想起 gSoap的http_get函数,该函数作用就是响应客户端的get请求,将wsdl文件发送出去,http://localhost:8090/ServiceReferences.ClientConfig不也是get请求们,在http_get函数里设断点验证,没错!接下来就好办了,改造http_get, 代码如下:(对http_get函数不了解的同学请查阅gSoap user guide)
{
string fileName = "ns.wsdl";
if(strstr(soap->msgbuf,"clientaccesspolicy.xml")!=NULL){
fileName = "clientaccesspolicy.xml";
}//红色乃添加的代码
FILE*fd = NULL;
fd = fopen(fileName.c_str(), "rb"); //open WSDL file to copy
if (!fd)
{
return 404; //return HTTP not found error
}
soap->http_content = "text/xml"; //HTTP header with text /xml content
soap_response(soap,SOAP_FILE);
for(;;)
{
size_t r = fread(soap->tmpbuf,1, sizeof(soap->tmpbuf), fd);
if (!r)
{
break;
}
if (soap_send_raw(soap, soap->tmpbuf, r))
{
break; //cannot send, but little we can do about that
}
}
fclose(fd);
soap_end_send(soap);
return SOAP_OK;
}
别忘了把clientaccesspolicy.xml拷到程序目录,当然也可以指定路径。 问题解决!同理,
2.gSoap服务端有个结构体是这么定义的:
{
xsd__string *__ptr;
xsd__int __size;
};
用于传递字符串数组,例如设备支持的云台协议名称,当然你也可以用一个字符串,用某个符号做分割,可是我还是喜欢用数组。
gSoap自动生成的wsdl,相应的描述如下:
<complexContent>
<restriction base="SOAP-ENC:Array">
<sequence>
<element name="item" type="xsd:string" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
</sequence>
<attribute ref="SOAP-ENC:arrayType" WSDL:arrayType="xsd:string[]"/>
</restriction>
</complexContent>
</complexType>
用Silverlight引用web service时老是报错,首条警告信息就是不支持arrayType,google一圈没什么有价值的资料,问题依旧无法解决。想起java写的ws就有返回数组的,为什么SL就能引用成功?看了一下java写的ws的wsdl,关于数组的描述如下:
- <xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="tns:sipDevUser" />
</xs:sequence>
</xs:complexType>
果然有所差距啊,看来问题出在wsdl上,手动改吧,改后的版本:
<sequence>
<element name="item" type="xsd:string" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
</sequence>
</complexType>
保存,启动ws, sl添加引用,通过-----:D 看到了代理类里面可爱的数组了。。。
附录:
Silverlight项目的ServiceReferences.ClientConfig文件
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="PatCsgServiceSoap" maxBufferSize="65536" maxReceivedMessageSize="65536">
<security mode="None" />
</binding>
<binding name="Service" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.1.19:8090" binding="basicHttpBinding"
bindingConfiguration="PatCsgServiceSoap" contract="WsPatCsg.ServicePortType"
name="PatCsgService_EndPoint" />
</client>
</system.serviceModel>
</configuration>
clientaccesspolicy.xml
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
浙公网安备 33010602011771号