问题
I am trying to call a web service from an iOS app. I have developed that service in WCF. The web service is hosted on IIS configured with BasicHTTPBinding. I have developed a simple iOS app that calls that web service hosted on a remote PC.
The iOS app is working fine but the SOAP service doesn't seem to understand the request I am sending from the iOS app. Here are all the details, the error I get is at the end.
The WSDL of web service is:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://tempuri.org/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="SLService" targetNamespace="http://tempuri.org/">
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://10.211.55.4/TestService/SLService.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://10.211.55.4/TestService/SLService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="ISLService_DoWork_InputMessage">
<wsdl:part name="parameters" element="tns:DoWork"/>
</wsdl:message>
<wsdl:message name="ISLService_DoWork_OutputMessage">
<wsdl:part name="parameters" element="tns:DoWorkResponse"/>
</wsdl:message>
<wsdl:portType name="ISLService">
<wsdl:operation name="DoWork">
<wsdl:input wsaw:Action="http://tempuri.org/ISLService/DoWork" message="tns:ISLService_DoWork_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/ISLService/DoWorkResponse" message="tns:ISLService_DoWork_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_ISLService" type="tns:ISLService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="DoWork">
<soap:operation soapAction="http://tempuri.org/ISLService/DoWork" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SLService">
<wsdl:port name="BasicHttpBinding_ISLService" binding="tns:BasicHttpBinding_ISLService">
<soap:address location="http://10.211.55.4/TestService/SLService.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Here is how I am making the SOAP request in iOS, the problem is most probably here:
NSString *soapMessage = [NSString stringWithFormat:@"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body><DoWork></DoWork></SOAP-ENV:Body></SOAP-ENV:Envelope>"];
NSURL *url=[NSURL URLWithString:@"http://10.211.55.4/TestService/SLService.svc/"];
NSMutableURLRequest *theRequest= [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];
[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[theRequest addValue: @"urn:SLService/DoWork" forHTTPHeaderField:@"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
responseData = [[NSMutableData data] retain];
} else {
messageTextView.text=@"Failed";
}
Here is what's inside the WCF Web Service class:
namespace TestSilverlight.Web{
public class SLService : ISLService
{
public string DoWork()
{
return "Service Works!";
}
}}
Here is the content of web.config file in WCF web service:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
Here is the SOAP response (error) I get in the responseData object:
a:ActionNotSupportedThe message with Action 'urn:ISLService/DoWork' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
I suck at asking questions here, I hope you guys understand this one. Please help.
回答1:
The problem is with your SOAPAction header. I suspect the issue is the same as this calling wcf webservice using basichttpbinding without REST or JSON.
The solution will be to change your SOAPAction from
urn:SLService/DoWork
to
http://tempuri.org/SLService/DoWork
or maybe even
http://tempuri.org/ISLService/DoWork
来源:https://stackoverflow.com/questions/8230530/recieving-soap-error-when-requesting-a-wcf-web-service-in-objective-c-ios-app