在iOS App中使用SOAP webservice时出现以下错误
"No Action header was found with namespace 'http://www.w3.org/2005/08/addressing' for the given message."
同样的Web服务在SOAP UI工具中运行良好。
以下是请求格式
NSString *data = @"<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:tem=\"http://tempuri.org/\">
<soap:Header></soap:Header>
<soap:Body><tem:GetEvaluators></tem:GetEvaluators></soap:Body>
</soap:Envelope>";
NSString *url = @"webservice url";
NSData *postData = [data dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:url]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:postData];
[request setTimeoutInterval:20.0];
[request setValue:@"application/soap+xml;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"http://tempuri.org/IATCService/GetEvaluators" forHTTPHeaderField:@"SOAPAction"];
NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
从webservice
收到完整的错误回复<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/fault</a:Action>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode>
<s:Value>a:MessageAddressingHeaderRequired</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-US">No Action header was found with namespace 'http://www.w3.org/2005/08/addressing' for the given message.</s:Text>
</s:Reason>
<s:Detail>
<a:ProblemHeaderQName>a:Action</a:ProblemHeaderQName>
</s:Detail>
</s:Fault>
</s:Body>
任何帮助都非常感激。
答案 0 :(得分:11)
我们遇到了与基于ASP.NET的服务器相同的问题(使用python / suds时出现错误消息,同样的查询在SoapUi中工作);经过大量挖掘,我们发现需要添加一个包含动作的SOAP头(作为XML元素);在Content-Type或SOAPAction标头中执行操作是不够的(但也不会受到伤害)。以下是成功查询的示例(来自SoapUi):
<SOAP-ENV:Envelope xmlns:ns0="..." xmlns:ns1="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope">
<SOAP-ENV:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>http://www.foo.com/.../SomeJob/getParameters</wsa:Action></SOAP-ENV:Header>
<ns1:Body>
<ns0:getParameters>...</ns0:getParameters>
</ns1:Body>
</SOAP-ENV:Envelope>
使用Python和SUDS,我们就是这样做的:
from suds.sax.element import Element
wsans = ('wsa', "http://www.w3.org/2005/08/addressing")
client.set_options(soapheaders = Element('Action', ns=wsans).setText(action))
可以从方法中查询操作,即如果要调用方法client.service.foo,请使用
action = client.service.foo.method.soap.action
我们通过查看SoapUi HTTP日志找到了这个。 (我们也尝试过Wireshark,但这不起作用,因为我们试图使用我们不拥有的https服务器。)
答案 1 :(得分:0)
包含
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
答案 2 :(得分:0)
最后我能解决这个问题,内容类型和请求格式与我传递请求的内容完全不同
Content-Type: application/soap+xml;charset=UTF-8;action="http://tempuri.org/IATCService/GetEvaluators"
所以区别在于我必须通过内容类型传递动作。
请求Soap Envelop与不同的命名空间完全不同
<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">
**<s:Header>
<a:Action s:mustUnderstand=\"1\">http://tempuri.org/IATCService/GetEvaluators</a:Action> </s:Header>**
<s:Body>
<GetEvaluators xmlns=\"http://tempuri.org/\"/></s:Body>
</s:Envelope>
由于标题信息也完全不同,我们必须在那里指定行动。
希望对遇到同样问题的人有所帮助。