WCF Username and Password in SOAP Header - c#

I'm trying to get a WCF client to call a web service with security information provided in the SOAP Header of the request, as follows.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ah_etas_order="http://types.defra.gov.uk/ahw/eartagging/order"
xmlns:ah_common="http://types.defra.gov.uk/ahw/common/complextypes"
xmlns:ah_assettype="http://types.defra.gov.uk/ahw/asset"
xmlns:ah_ref_data_sets="http://types.defra.gov.uk/ahw/common/referencedatasets"
xmlns:ah_custtype="http://types.defra.gov.uk/ahw/customer"
xmlns:m5="http://types.defra.gov.uk/bs7666"
xmlns:m6="http://www.govtalk.gov.uk/people/bs7666"
xmlns:m7="http://types.defra.gov.uk/ahw/common/derivedtypes"
xmlns:ah_etas_type="http://types.defra.gov.uk/ahw/eartagging">
<SOAP-ENV:Header xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Security soap:role="system" soap:mustUnderstand="true">
<wsse:UsernameToken>
<wsse:Username>username here</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password here</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>...</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I'm using Visual Studio 2012 and .NET 4. The docs say the version of SOAP messaging used for CARA Services is SOAP 1.2.
I've added a service reference with has added a web.config file with an endpoint and the following custom binding.
<customBinding>
<binding name="ProcessOrderBinding">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
</customBinding>
I've tried lots of different web.config options but can't seem to get the correct soap header. Can anyone point me in the right direction?
Update:
#Yaron, Here is the soap header using your binding. I've added a includeTimestamp=false to remove the timestamp.
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<h:Security xmlns:h="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">
uIDPoxqYDT0sMwVImscgqVaf7GYAAAAAjin6KftLjkaS2CW99IXxrnWGCjfQnzFFuf4zGaQpeqIACQAA
</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken u:Id="uuid-79885712-d6eb-451c-9483-4df2b68722bd-1">
<o:Username>username here</o:Username>
<o:Password>password here</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">...</s:Body>
</s:Envelope>
As you can see it's missing the following before the password.
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">

Use this binding:
<customBinding>
<binding name="NewBinding0">
<textMessageEncoding messageVersion="Soap12" />
<security authenticationMode="UserNameOverTransport">
<secureConversationBootstrap />
</security>
<httpsTransport />
</binding>
</customBinding>
Of course you also need to supply user/pass on the proxy:
proxy.ClientCredentials.Username.Username = "user"
proxy.ClientCredentials.Username.Password = "pass"
All this assumes you also use SSL. If you don't then check out CUB.

Related

Wcf service server - authentication with usernametoken

we are trying to create server from given demo wsdl. Wsdl does not contains security but we need implement usernametoken where request header looks like this:
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:env="http://www.w3.org/2003/05/soap-envelope" env:mustUnderstand="true">
<wsse:UsernameToken wsu:Id="UsernameToken-7dd435a5-b8bb-4388-bba3-f77512a14351">
<wsse:Username>CES</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">e8I23Z92JGgSREAb=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">v21JzUcrKZiZ7MC==</wsse:Nonce>
<wsu:Created>2017-10-13T13:00:02.221Z</wsu:Created>
</wsse:UsernameToken>
<wsse:SecurityTokenReference>
<wsse:Embedded wsse:ValueType="http://www.asktirweb.org/security/authentication/username" wsu:Id="alex"/>
</wsse:SecurityTokenReference>
</wsse:Security>
<Action xmlns="http://www.w3.org/2005/08/addressing">http://www.asktirweb.org/services/TIRAccountingService-1/sendInvoice</Action>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:321a0dff-61a8-4eae-8934-7f06e8d87648</MessageID>
<To xmlns="http://www.w3.org/2005/08/addressing">http://wiesbaden:8040/askdemo/hs/AskTirWebDemo/WsSecurityRequests</To>
<ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
</soap:Header>
Any suggestions ?
Please try the below custom binding, it might be useful to you.
<customBinding>
<binding name="mybinding">
<textMessageEncoding messageVersion="Soap12WSAddressing10">
</textMessageEncoding>
<security authenticationMode="UserNameOverTransport" includeTimestamp="false" >
</security>
<httpsTransport></httpsTransport>
</binding>
</customBinding>
And the request body captured by Fiddle.
Besides, can we use the WSDL file to generate the client configuration, which has contained the essential binding type and security authentication mode? Like the below Tools.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/servicemodel-metadata-utility-tool-svcutil-exe
By default, it is a built-in tool in VS Developer Command Prompts.
svcutil https://vabqia969vm:21011
It will generate the output.config in the current directory, it contains the binding configuration to be used in WCF.
Feel free to let me know if there is anything I can help with.

How to log full raw WCF client request from client side?

I have a WCF client with TransportWithMessageCredential security mode. When try to log request using BeforeSendRequest
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\tmp\\request_log.xml");
file.WriteLine(request.ToString());
file.Close();
return null;
}
have result without security tags
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">https://(skiped)</Action>
</s:Header>
<s:Body>
...
</s:Body>
</s:Envelope>
How can I log full raw request in client? It must be like this
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>...</u:Created>
<u:Expires>..</u:Expires>
</u:Timestamp>
<o:BinarySecurityToken>
<!-- Removed-->
</o:BinarySecurityToken>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
...
</SignedInfo>
<SignatureValue>...</SignatureValue>
<KeyInfo>
<o:SecurityTokenReference>
...
</o:SecurityTokenReference>
</KeyInfo>
</Signature>
</o:Security>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">skiped</Action>
</s:Header>
<s:Body>
...
</s:Body>
</s:Envelope>
UPD. Security options for binding
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Basic256" />
</security>
I didn't found how to do this in C# but had captured raw request using
Charles SSL proxying
The request contains all security tags.
The article which helped me so much Tracing-WCF-Messages
This may help:
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
Log("Request:" + Environment.NewLine + buffer.CreateMessage());
return null;
}
You can also use Fiddler which is free.
If your endpoint is https be sure to bypass certificate validation with this
ServicePointManager.ServerCertificateValidationCallback = delegate {return true;};
because Fiddler uses its own certificate that is invalid for your connection.

WCF C# Soap service not rendering correctly

I am trying to make a SOAP call to a webservice.
According to the manual the SOAP call should look like this:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsswssecurity-secext-1.0.xsd"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:vh="http://vedaxml.com/soap/header/v-header-v1-9.xsd"
xmlns:idm="http://vedaxml.com/vxml2/idmatrix-v4-0.xsd">
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>****</wsse:Username>
<wsse:Password>****</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous
</wsa:Address>
</wsa:ReplyTo>
<wsa:To>http://vedaxml.com/sys2/idmatrix-v4</wsa:To>
<wsa:Action>http://vedaxml.com/idmatrix/VerifyIdentity</wsa:Action>
<wsa:MessageID>Quick_Request_1</wsa:MessageID>
</soapenv:Header>
<soapenv:Body>
<idm:request client-reference="Quick Connect Ref"
reason-for-enquiry="Quick Connect">
<idm:individual-name>
<idm:family-name>Potter</idm:family-name>
<idm:first-given-name>Harry</idm:first-given-name>
<idm:other-given-name>James</idm:other-given-name>
</idm:individual-name>
<idm:date-of-birth>1980-07-31</idm:date-of-birth>
<idm:current-address>
<idm:property>Potter Manor</idm:property>
<idm:unit-number>3</idm:unit-number>
<idm:street-number>4</idm:street-number>
<idm:street-name>Privet</idm:street-name>
<idm:street-type>Drive</idm:street-type>
<idm:suburb>Little Whinging</idm:suburb>
<idm:state>NSW</idm:state>
<idm:postcode>2999</idm:postcode>
</idm:current-address>
</idm:request>
</soapenv:Body>
</soapenv:Envelope>
The company has provided me with a WSDL file. Which I have imported into C# as both a Service Reference and a Web Reference (Because I couldnt get service reference working)
First of all I tried a Service Reference, no bindings were created in web.config when I imported the WSDL file, So I programmatically added the bindings. This is my code:
BasicHttpsBinding binding = new BasicHttpsBinding(securityMode: BasicHttpsSecurityMode.TransportWithMessageCredential);
EndpointAddress address = new EndpointAddress("https://ctaau.vedaxml.com/cta/sys2/idmatrix-v4");
ServiceReference1.identitydetails idDetails = new ServiceReference1.identitydetails();
ServiceReference1.IdMatrixPortTypeClient client = new ServiceReference1.IdMatrixPortTypeClient(binding, address);
ServiceReference1.request request = new ServiceReference1.request();
request.individualname = new ServiceReference1.individualnameType();
request.individualname.familyname = "Doe";
request.individualname.firstgivenname = "John";
request.dateofbirth = new DateTime(1982, 6, 30);
client.ClientCredentials.UserName.Password = "myPassword";
client.ClientCredentials.UserName.UserName = "myUsername";
var response = client.IdMatrixOperation(request);
The resposne failed, so I checked the POST with Fiddler. It was coming up completely different to the required post.
Fiddler showed me:
POST https://ctaau.vedaxml.com/cta/sys2/idmatrix-v4 HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://vedaxml.com/idmatrix/VerifyIdentity"
Host: ctaau.vedaxml.com
Content-Length: 1216
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo/2Z+y84o0RBobFBWyoF5bwAAAAAMq+GwwIcokm+lVAU/kPq4mJScS+4yh9ElAQSyM2iUqMACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2016-03-23T01:23:53.921Z</u:Created>
<u:Expires>2016-03-23T01:28:53.921Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-f3068a37-421c-4b81-93c6-ef622def918a-1">
<o:Username>myUsername</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">myPassword</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<request xmlns="http://vedaxml.com/vxml2/idmatrix-v4-0.xsd">
<individual-name>
<family-name>Doe</family-name>
<first-given-name>John</first-given-name>
</individual-name>
</request>
</s:Body>
</s:Envelope>
As you can see the WSSE name space is incorrect. I dont have WS-Addressing and The Prefix's are all wrong?
So then I moved to A Web Reference. I needed to get WS-Secrutiy working, so I changed the client protocol to WebServicesClientProtocol.
This is my code:
WebReference.idmatrix idMatrix = new WebReference.idmatrix();
WebReference.request request = new WebReference.request();
request.individualname = new WebReference.individualnameType();
request.individualname.familyname = "Potter";
request.individualname.othergivenname = names;
request.individualname.firstgivenname = "Harry";
request.dateofbirth = new DateTime(1980, 7, 31);
UsernameToken userToken = new UsernameToken("myusername", "mypassword", PasswordOption.SendPlainText);
SoapContext requestContext = idMatrix.RequestSoapContext;
requestContext.Security.Tokens.Add(userToken);
var test = idMatrix.IdMatrixOperation(request);
The Post in fidder looks like:
POST https://vedaxml.com/sys2/idmatrix-v4 HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.42000)
VsDebuggerCausalityData: uIDPo+bosvSda9ZIvNIXrG1tEbIAAAAAH4GKWz0+uU2A4pOErBrkw2fytXzxQh9Jp4TpqUiqXHoACQAA
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://vedaxml.com/idmatrix/VerifyIdentity"
Host: vedaxml.com
Content-Length: 1768
Expect: 100-continue
Connection: Keep-Alive
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action>http://vedaxml.com/idmatrix/VerifyIdentity</wsa:Action>
<wsa:MessageID>uuid:d1a0cf65-cee3-467d-9f98-b72cbd3d4e5a</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>https://vedaxml.com/sys2/idmatrix-v4</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="Timestamp-5fbc1707-8d36-4091-804d-4c19ec06f7bd">
<wsu:Created>2016-03-23T01:26:31Z</wsu:Created>
<wsu:Expires>2016-03-23T01:31:31Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-4803d49a-e2c3-45f5-bf18-7c0b5cd7d130">
<wsse:Username>myusername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">mypassword</wsse:Password>
<wsse:Nonce>sc5Dgf/vhU+YTZjdLQZsLw==</wsse:Nonce>
<wsu:Created>2016-03-23T01:26:31Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<request xmlns="http://vedaxml.com/vxml2/idmatrix-v4-0.xsd">
<individual-name>
<family-name>Potter</family-name>
<first-given-name>Harry</first-given-name>
<other-given-name>James</other-given-name>
</individual-name>
</request>
</soap:Body>
</soap:Envelope>
Its a little closer, but some of the namespaces are still wrong, and the prefexis are wrong too.
It needs to be soapenv: and in the body needs to be idm:
How can I fix the namespaces and prefix's in C#?
So I finally solved my problem. I will post everything I have learnt. First of all, Prefix's do not mean anything.
and are the same thing, the prefix only relates to the namespace ie:
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" = <s:envelope>
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" = <soap:envelope>
both of these are equivalent.
Secondly what I needed to do was get WS-Security and WS-Addressing and Soap V1.1 (not v1.2) working as this was required by the server.
To do this, I had to create a custom binding. In Web.config:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="WsHttpSoap11">
<textMessageEncoding messageVersion="Soap11WSAddressing10"></textMessageEncoding>
<security authenticationMode="UserNameOverTransport"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11"
securityHeaderLayout="Lax"
includeTimestamp="false"
requireDerivedKeys="false" >
</security>
<httpsTransport></httpsTransport>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="<my endpoint url>" binding="customBinding" bindingConfiguration="WsHttpSoap11" contract="ServiceReference1.IdMatrixPortType" name="testBinding" ></endpoint>
</client>
I checked the output with Fiddler, and all the correct namespaces were being created.
In conclusion, I hope everyone in the future moves away from SOAP and runs towards Oauth + RESTfull applications.

400 Bad Request Exception: Simple SOAP WCF service with small data

I have a simple WCF service suing SOAP. I have a very simple operation “GetMultiplied “ with very small amount of data. I am getting following exception when client try to call the operation. Any idea what all could be the issues?
Inner Exception: {"The remote server returned an error: (400) Bad Request."}
Complete wsdl and schema is listed at the end.
Note: I have set quota values, maxBufferSize etc to higher values in both service and client config.
Tracing in Service
When I used tracing in service (based on How to turn on WCF tracing?), I am getting the following - seems like there is no error logged.
<Type>3</Type>
<SubType Name="Information">0</SubType>
<Level>8</Level>
<TimeCreated SystemTime="2012-09-13T17:05:17.6059181Z" />
<Source Name="System.ServiceModel" />
<Description>AppDomain unloading.</Description>
Service implementation
public class CalculationService : ICalculationService
{
public virtual GetMultipliedResponse GetMultiplied(GetMultipliedRequest request)
{
MultipliedResult result = new MultipliedResult();
result.ResultNumber= ((request.InputNumber)*2);
GetMultipliedResponse response = new GetMultipliedResponse(result);
return response;
}
}
Client
static void Main(string[] args)
{
CalculationServiceInterfaceClient proxy = new CalculationServiceInterfaceClient();
multipliedResult result = proxy.getMultiplied(2);
}
In the auto generated code the detail is:
public NewClient.CalcReference.multipliedResult getMultiplied(int inputNumber)
{
NewClient.CalcReference.getMultipliedRequest inValue = new NewClient.CalcReference.getMultipliedRequest();
inValue.inputNumber = inputNumber;
NewClient.CalcReference.getMultipliedResponse retVal = ((NewClient.CalcReference.CalculationServiceInterface)(this)).getMultiplied(inValue);
return retVal.restaurants;
}
WSDL
<definitions xmlns:import0="urn:lijo:demos:multiplyservice:messages:v1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:import1="urn:lijo:demos:multiplyservice:data:v1" xmlns:tns="urn:lijo:demos:multiplyservice:calculation:v1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" name="CalculationService" targetNamespace="urn:lijo:demos:multiplyservice:calculation:v1" xmlns="http://schemas.xmlsoap.org/wsdl/">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" />
<types>
<xsd:schema>
<xsd:import schemaLocation="C:\toolbox\LijosServiceApp\NewService\RestaurantMessages.xsd" namespace="urn:lijo:demos:multiplyservice:messages:v1" />
<xsd:import schemaLocation="C:\toolbox\LijosServiceApp\NewService\RestaurantData.xsd" namespace="urn:lijo:demos:multiplyservice:data:v1" />
</xsd:schema>
</types>
<message name="getMultipliedIn">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" />
<part name="parameters" element="import0:getMultiplied" />
</message>
<message name="getMultipliedOut">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" />
<part name="parameters" element="import0:getMultipliedResponse" />
</message>
<portType name="CalculationServiceInterface">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" />
<operation name="getMultiplied">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" />
<input message="tns:getMultipliedIn" />
<output message="tns:getMultipliedOut" />
</operation>
</portType>
<binding name="BasicHttpBinding_CalculationServiceInterface" type="tns:CalculationServiceInterface">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="getMultiplied">
<soap:operation soapAction="urn:lijo:demos:multiplyservice:calculation:v1:getMultipliedIn" style="document" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="CalculationServicePort">
<port name="CalculationServicePort" binding="tns:BasicHttpBinding_CalculationServiceInterface">
<soap:address location="http://localhost/CalculationService" />
</port>
</service>
</definitions>
XSD
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="RestaurantData" targetNamespace="urn:lijo:demos:multiplyservice:data:v1"
elementFormDefault="qualified" xmlns="urn:lijo:demos:multiplyservice:data:v1"
xmlns:mstns="urn:lijo:demos:multiplyservice:data:v1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="multipliedResult">
<xs:sequence>
<xs:element name="resultNumber" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Cleint Config (Autogenerated)
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_CalculationServiceInterface"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard" maxBufferSize="65536"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="524288" maxStringContentLength="524288" maxArrayLength="524288"
maxBytesPerRead="524288" maxNameTableCharCount="524288" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/CalculationService" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_CalculationServiceInterface"
contract="CalcReference.CalculationServiceInterface" name="CalculationServicePort" />
</client>
</system.serviceModel>
I solved the problem :-)
I will publish the answer for the benefit of others.
Key problem: I was trying to use the manually created wsdl. (I reffered the local copy available inside service - I was using a tool to generate the service code from wsdl). The service was not providing it. I should have tried to view the wsdl from browsing the svc file
Ran the service using WcfTestClient. Gave an error that revealed the project name and the namespace that we use should be same. (Otherwise it will append the project name before the namespace name and that will become incorrect namespace)
Type the “WcfTestClient” command in “Visual Studio Command Prompt”. http://blogs.msdn.com/b/wcftoolsteamblog/archive/2010/01/04/tips-for-launching-wcf-test-client.aspx
By browsing the svc file in the service, it showed that the metadata publishing is not enabled. Added a service behavior for meta data browsing in the web.config.
Used relative path for the service (instead of localhost) error "No protocol binding matches the given address ..."
Service Tracing also can be helpful (though did not help me here). Used "C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\SvcTraceViewer.exe". Followed the post and the Error file (initializeData="Error.svclog") is stored inside the solution project. Changing it to other locations did not work. How to turn on WCF tracing?
Refer One WCF service – two clients; One client does not work

Calling PHP webservice from .Net

I have created a Webservice in PHP and I'm trying to call it from my C# code.
When I try to create a proxy using wsdl utility
wsdl http://localhost:5365/DemoService.php?wsdl
I get this errors
Error: Cannot find definition for http://myserver.co.za/sayHello:sayHelloPortType.
Service Description with namespace http://myserver.co.za/sayHello is missing.
Parameter name: name
Here's my Webservice code (DemoService.php)
<?php
function sayHello($name){
$salutation = "Hi $name !";
return $salutation;
}
$server = new SoapServer("greetings.wsdl");
$server->addFunction("sayHello");
$server->handle();
?>
and my WSDL code (greetings.wsdl)
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='greetings'
targetNamespace='http://myserver.co.za/sayHello'
xmlns:tns=' http://myserver.co.za/sayHello'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
<message name='sayHelloRequest'>
<part name='name' type='xsd:string'/>
</message>
<message name='sayHelloResponse'>
<part name='salutation' type='xsd:string'/>
</message>
<portType name='sayHelloPortType'>
<operation name='sayHello'>
<input message='tns:sayHelloRequest'/>
<output message='tns:sayHelloResponse'/>
</operation>
</portType>
<binding name='sayHelloBinding' type='tns:sayHelloPortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='sayHello'>
<soap:operation soapAction=''/>
<input>
<soap:body use='encoded' namespace=''
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace=''
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>
<documentation>This is Wiley's SOAP server Example</documentation>
<service name='sayHelloService'>
<port name='sayHelloPort' binding='sayHelloBinding'>
<soap:address location='http://localhost:5365/DemoService.php'/>
</port>
</service>
</definitions>
I really don't understand what it is trying to say. Can some one point me in a right direction?
Here is what is wrong with the WSDL
First the xmlns:tns namespace has a space at the start of it
xmlns:tns=' http://myserver.co.za/sayHello' <-- Bad
xmlns:tns='http://myserver.co.za/sayHello' <-- Good
Next the <documentation> node is in the wrong place, it should be inside the <service> node like so
<service ...>
<documentation>This is Wiley's SOAP server Example</documentation>
<port ...>
...
</port>
</service>
Your port binding element needs to use the tns namespace
<port name='sayHelloPort' binding='sayHelloBinding'> <-- Bad
<port name='sayHelloPort' binding='tns:sayHelloBinding'> <-- Good
Finally I could not get the soap:body to import as encoded, and had to swap them to literal, also note they need a value in the namespace element
<soap:body use='literal' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
I believe the soapAction element in the <soap:operation soapAction=''/> node still needs a value to work correctly, something like urn:xmethods-delayed-quotes#sayHello, but it will import without it.
Full WSDL (I caan import this using WSDL.exe without error)
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='greetings'
targetNamespace='http://myserver.co.za/sayHello'
xmlns:tns='http://myserver.co.za/sayHello'
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
<message name='sayHelloRequest'>
<part name='name1' type='xsd:string'/>
</message>
<message name='sayHelloResponse'>
<part name='salutation' type='xsd:string'/>
</message>
<portType name='sayHelloPortType'>
<operation name='sayHello'>
<input message='tns:sayHelloRequest'/>
<output message='tns:sayHelloResponse'/>
</operation>
</portType>
<binding name='sayHelloBinding' type='tns:sayHelloPortType'>
<soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='sayHello'>
<soap:operation soapAction=''/>
<input>
<soap:body use='literal' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='literal' namespace='urn:xmethods-delayed-quotes' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>
<service name='sayHelloService'>
<documentation>Service Description</documentation>
<port name='sayHelloPort' binding='tns:sayHelloBinding'>
<soap:address location='http://localhost:5365/DemoService.php'/>
</port>
</service>
</definitions>
Why don't you add the reference to the web service through:
right-click on project file -> add web reference --> type in the url to the webservice and voila!
This should create the necessary entries in Web.config (or App.config) plus the proxy classes that you'll use in your app.

Categories