One WCF service – two clients; One client does not work - c#

I have one WCF service and two console app clients.
Service: The service code is created from a wsdl contact using WCSF Blue tool.
Client 1: This client is using wsdl that is obtained by browsing the svc file. This browsed wsdl file is slightly different from the contract wsdl file.
Client 2: This client is created using the original wsdl contract.
Cleint1 is working fine. Client 2 is not working. What all could be potential issues?
App.Config file of both the clients look similar – only the name changes. I think, the problem will be in the client C# code generated – most probably in the Action – ReplyAction. What need to be corrected here?
One noticeable difference is in Action and ReplyAction
Client 1:
Action="urn:lijo:demos:multiplyservice:calculation:v1/ICalculationService/GetMultiplied", ReplyAction="urn:lijo:demos:multiplyservice:calculation:v1/ICalculationService/GetMultipliedRe" +
"sponse"
Client 2:
Action="urn:lijo:demos:multiplyservice:calculation:v1:getMultipliedIn", ReplyAction="*"
Trace Message
The message with Action 'urn:lijo:demos:multiplyservice:calculation:v1:getMultipliedIn' 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).
EDIT
This can be corrected by changing the Action and ReplyAction as below (Copied it from Service).
[System.ServiceModel.OperationContractAttribute(Action = "urn:lijo:demos:multiplyservice:calculation:v1/ICalculationService/getMultiplied", ReplyAction = "urn:lijo:demos:multiplyservice:calculation:v1/ICalculationService/getMultipliedRe" +
"sponse")]
Note: It is important to ensure that the casing in the service is correct (i.e, getMultiplied not GetMultiplied)
Copying from the service is not a good option, though it works. What would be the correct Action and ReplyAction?
Also, Can you please point out how to modify the wsdl so that the ReplyAction will be correct in the generated client proxy? That is the essential part to mark it as answered.
WCF: Actions, Asterisk and Metadata
WsdlExporter, which is used for metadata publishing, ignores operations with asterisk actions (both Action and ReplyAction).
From MSDN -ReplyAction Property
Specifying an asterisk in the service instructs WCF not to add a reply action to the message, which is useful if you are programming against messages directly.
REFERENCES:
WCF metadata missing operations
RestaurantData.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>
Original Contract 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>

I figured it out. For the benefit of others I will explain it here.
Before that please refer answer to the 400 Bad Request Exception: Simple SOAP WCF service with small data for some debugging ideas.
This due to Format SOAP Action option in WCSF Blue tool.
I have used "Format Soap Actions" while generating the code using WCSF Blue. But while client, I did not use the tool. That mismatch is the key issue.
Format Soap Actions force the SOAP actions (Action and ReplyAction) applied to each operation contract follow the standard WCF format:
<namespace>/<service>/<operation>[Response]
If I have no control over the client, I should not use Format SOAP Action option in WCSF Blue Tool.
Please refer Service works from wcfTestClient but fails in Console Application for a working example.
[Still I have a question - what if I have no control over the client still need to use ReplyAction? What will be the URI in xml format in such scenario that is to be used in the client and service ? ]
General Debugging Ideas:
Ensure that the service is good by using wcfTestClient (type wcfTestClient in VS command prompt to launch)
Use Tracing as mentioned in How to turn on WCF tracing?
Verify that the configuration values are in web.config/app.config and not in output.config (in case of auto generation using tools)
Verify that you are referring proper wsdl (is it local file or url from running service?)
Verify that the wsdl can be viewed by browsing the svc file. Metadata is enabled
Check whether it is relative path or absolute path in the "address" in the service

You are right that there is an issue in ReplyAction. When ReplyAction is set to "*" makes WCF to ignore that operation. Correct the ReplyAction to your operation contract will work.
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/41f5fe72-3ab3-4741-867e-a93119fe62aa

Related

WCF Webservice always returning null

I am consuming a SOAP webservice from our ticket system OTRS. So the Webservice is not really under my control.
The request works just fine, but i am never getting an answer in my Code. The answer is always null. (var response = client.SessionCreate(session);)
The strange thing is, that wireshark and the webservice console of that ticket system are saying that i should receive a valid answer.
Since i am very new to this webservice stuff so i have absolutely no idea where to start in this case. So here is a description of that i did. Any suggestion is really appreciated.
First i created a normal C# project and added the WSDL file which can be found only on the GitHub site website of the OTRS project. I added it as a Service Reference and than added my C# code which looks like this.
// For Debug
System.Net.ServicePointManager.Expect100Continue = false;
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-us");
try
{
OTRS.OTRS_Error err = new OTRS.OTRS_Error();
OTRS.GenericTicketConnector_PortTypeClient client = new OTRS.GenericTicketConnector_PortTypeClient("GenericTicketConnector_Port");
OTRS.SessionCreate session = new OTRS.SessionCreate();
session.Item = "someUserNameGoesHere";
session.ItemElementName = OTRS.ItemChoiceType8.UserLogin;
session.Password = "SomePasswordGoesHere";
var response = client.SessionCreate(session);
Console.WriteLine(response.SessionID);
Console.WriteLine(response.Error);
}
catch (Exception exep)
{
Console.WriteLine(exep.Message);
Console.WriteLine(exep.InnerException);
}
finally
{
Console.ReadLine();
}
Incoming message at serverside
<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.otrs.org/TicketConnector/SessionCreate</a:Action>
<a:MessageID>urn:uuid:14750529-3de2-4618-8db4-8ac18b681c18</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">http://SomeServer/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnector</a:To>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SessionCreate xmlns="http://www.otrs.org/TicketConnector/">
<UserLogin xmlns="">someUserName</UserLogin>
<Password xmlns="">somePassword</Password>
</SessionCreate>
</s:Body>
Outgoing message at serverside
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<SessionCreateResponse xmlns="http://www.otrs.org/TicketConnector/">
<SessionID>SomeSessionID</SessionID>
</SessionCreateResponse>
</soap:Body>
</soap:Envelope>
Wireshark HTTP/XML package going from the server to my client
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding"
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<SessionCreateResponse xmlns="http://www.otrs.org/TicketConnector/">
<SessionID>SomeSessionID</SessionID>
</SessionCreateResponse>
</soap:Body>
</soap:Envelope>
Refernce.cs
https://gist.github.com/HansVader/1ba3847d918ee15ef16703c8ada6c9bf
WSDL
https://gist.github.com/HansVader/dd849e49f4a1584397cd21b0e430b301
I currently only need the SessionnCreate and TicketUpdate function. The other operations are irrelevant at this point in time. Please let me know if you need any other informations.
Update:
Here are the traces from the trace tool like yildizm85 suggested in the comments:
I think it is also worth noting that i created the refernce.cs
by myself with the svcutil tool because i had a problem with the IsWrapped. Have a look at this question and answer:
XmlSerializer attribute not valid in Web Service using WCF
The WSDL does not define elementFormDefault:
<xsd:schema targetNamespace="http://www.otrs.org/TicketConnector/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
Since unqualified is default, this causes every property to be decorated with Form=System.Xml.Schema.XmlSchemaForm.Unqualified in the generated reference file.
But, since there is a default namespace specified for each complex object, the XML serializer will not process the unqualified properties.
The solution
Change the schema element to:
<xsd:schema targetNamespace="http://www.otrs.org/TicketConnector/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
Also, for some of the properties, the order is wrong, so they need to be changed to (for example TickerCreateResponse):
<xsd:element name="TicketCreateResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="ArticleID" type="xsd:positiveInteger"/>
<xsd:element maxOccurs="1" minOccurs="1" name="TicketID" type="xsd:positiveInteger"/>
<xsd:element minOccurs="1" name="TicketNumber" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="Error" type="tns:OTRS_Error"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
After these changes, create the proxy using svcutil:
svcutil.exe /serializer:XmlSerializer GenericTicketConnectorSOAP.wsdl /o:OtrsConnector.cs /wrapped /n:*,otrs
And using the config:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="GenericTicketConnector_Binding">
<textMessageEncoding messageVersion="Soap12" writeEncoding="utf-8" />
<httpTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://localhost/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnector"
binding="customBinding" bindingConfiguration="GenericTicketConnector_Binding"
contract="otrs.GenericTicketConnector_PortType" name="GenericTicketConnector_Port" />
</client>
</system.serviceModel>
It should work after that, at least it did for me.
Hope it works for you as well!

Error when try to create Service Reference in VS2013 with fault elements from third party WSDL

I am creating a WCF Client in VS 2013 using a supplied third party WSDL for a web service - most likely running on Java.
Running svcutil on the raw WSDL gives me an error similar to this:
Error: Cannot import wsdl:binding
Detail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.
XPath to wsdl:portType:
//wsdl:definitions[#targetNamespace='<ns>']/wsdl:portType[#name='xxxPort']
XPath to Error Source:
//wsdl:definitions[#targetNamespace='<ns>']/wsdl:binding[#name='xxxPortSoap11']
Error: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.
XPath to wsdl:binding:
//wsdl:definitions[#targetNamespace='<ns>']/wsdl:binding[#name='xxxPortSoap11']
XPath to Error Source:
//wsdl:definitions[#targetNamespace='<ns>']/wsdl:service[#name='xxxPortService']/wsdl:port[#name='xxxPortSoap11']
Generating files...
Warning: No code was generated. ...
In order to get the Service Reference working (or svcutil running without errors) I have to comment out the fault definitions in the port and bindings. I can live with that (as I have made a MessageInspector to pull out errors from the various detail elements), but want to get it working properly.
Simplifying the WSDL to only show the elements that give me problems gives:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions
xmlns:tns="http://www.example.com/data/common/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:sch0="http://www.example.com/data/common/"
targetNamespace="http://www.example.com/data/common/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns1="http://www.example.com/data/common/"
attributeFormDefault="unqualified" elementFormDefault="qualified"
targetNamespace="www.example.com/data/common/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType xmlns="http://www.w3.org/2001/XMLSchema" name="BusinessErrorType">
<xsd:sequence xmlns="http://www.w3.org/2001/XMLSchema">
<xsd:element xmlns="http://www.w3.org/2001/XMLSchema"
name="Error" maxOccurs="unbounded" type="string" />
</xsd:sequence>
</xsd:complexType>
<xsd:element xmlns="http://www.w3.org/2001/XMLSchema"
name="BusinessErrorFault" type="tns1:BusinessErrorType" />
</xsd:schema>
</wsdl:types>
<wsdl:message name="BusinessErrorFault">
<wsdl:part name="BusinessErrorFault" element="sch0:BusinessErrorFault" />
</wsdl:message>
<wsdl:portType name="ViewMessagesPort">
<wsdl:operation name="BusinessError">
<wsdl:fault name="BusinessErrorFault" message="sch0:BusinessErrorFault" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ViewMessagesPortSoap11" type="sch0:ViewMessagesPort">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="BusinessError">
<soap:operation soapAction="" />
<wsdl:fault name="BusinessErrorFault">
<soap:fault use="literal" name="BusinessErrorFault" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ViewMessagesPortService">
<wsdl:port name="ViewMessagesPortSoap11" binding="sch0:ViewMessagesPortSoap11">
<soap:address location="https://www.example.com/ws/" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I have looked at many SO questions and other places on the net including Scott Hanselman's breaking the rules with no joy.
Hopefully it is something blindingly obvious ... I gratefully await any answers from across the pond as I wend my way home in the UK.
UPDATE
Passing the above WSDL through https://www.wsdl-analyzer.com/ gives an error on the binding:
Style: Unknown [Warn!]
Could not detect the 'use' for the operations of binding ViewMessagesPortSoap11
I'm still none the wiser.
The WSDL you published above has an issue that there is no schema with targetNamespace of "http://www.example.com/data/common/" which is what expected by the sch0:BusinessErrorFault element. I assume this may be because you did not provide the full WSDL so I changed the targetNamespace of the schema to it. The next error if this this operation:
<wsdl:operation name="BusinessError">
<wsdl:fault name="BusinessErrorFault" message="sch0:BusinessErrorFault" />
</wsdl:operation>
has no input or output but just fault, which does not make since.
I guess this might also be because you simplified the WSDL so please publish the full one if you get more errors.

Eliminating tempuri from a WCF Web Service which has FaultException

Background:
I've recently added internal authentication of user requests to a web service with a custom FaultException being thrown in the event of a failed authentication.
The FaultException custom type has been marked up:
[DataContract(Namespace = ConstantConfig.ServiceNamespace, Name = "AuthenticationError")]
public class AuthenticationError
The Service Interface methods have been marked up:
[OperationContract]
[FaultContract(typeof(AuthenticationError), Namespace = ConstantConfig.ServiceNamespace)]
ClientReport GetClientReport(DateTime from, DateTime to);
The interface itself has been marked up:
[ServiceContract(Namespace = ConstantConfig.ServiceNamespace)]
public interface IClientReportService
The implementation of the interface has been marked up:
[ServiceBehavior(Namespace = ConstantConfig.ServiceNamespace)]
public class ClientReportService : IClientReportService
The web.config and the app.config are all pointing at the copy/pasted service namespace.
And yet, despite all of this, I am still getting a tempuri.wsdl getting generated. Here is a reprsentative excerpt from the wsdl:
Main:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://webservice.company.com/ClientReportService" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:i0="http://tempuri.org/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ClientReportService" targetNamespace="http://webservice.company.com/ClientReportService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:import namespace="http://tempuri.org/" location="http://localhost:4319/ClientReportService.svc?wsdl=wsdl0" />
<wsdl:types>
<xsd:schema targetNamespace="http://webservice.company.com/ClientReportService/Imports">
<xsd:import schemaLocation="http://localhost:4319/ClientReportService.svc?xsd=xsd0" namespace="http://webservice.company.com/ClientReportService" />
<xsd:import schemaLocation="http://localhost:4319/ClientReportService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
</xsd:schema>
</wsdl:types>
Tempuri:
<wsdl:operation name="GetClientReport">
<soap:operation soapAction="http://webservice.company.com/ClientReportService/IClientReportService/GetClientReport" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
<wsdl:fault name="AuthenticationErrorFault">
<soap:fault use="literal" name="AuthenticationErrorFault" namespace="" />
</wsdl:fault>
</wsdl:operation>
I'm guessing there is something that I have not marked up or marked up incorrectly, but am at a loss to find it.
Any suggestions?
try this
<endpoint address=""
binding="basicHttpBinding"
bindingNamespace="http://my.namespace.com"
contract=""/>
</service>
As it turns out the error was entirely mine.
In the web config the service name did not match the service name on the actual service.
Actual service (inside the markup for the .svc file):
Service="Company.Client.Framework.ReportService.ClientReportService"
Broken Web Config
<service name="Company.Client.ReportService.ReportService">
Corrected Web Config:
<service name="Company.Client.ReportService.ClientReportService">
After I corrected this and regenerated the WSDL, tempuri vanished.

Contract-First WCF for Salesforce Outbound Messaging

I am looking at implementing listener application for Salesforce Outbound Messaging.
The walk through implements it using the deprecated ASMX web service. The code is generated using wsdl.exe with /serverInterface switch.
Here is the wsdl of Salesforce Outbound Messaging.
<?xml version="1.0" encoding="UTF-8"?>
<definitions targetNamespace="http://soap.sforce.com/2005/09/outbound"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://soap.sforce.com/2005/09/outbound"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ent="urn:enterprise.soap.sforce.com"
xmlns:ens="urn:sobject.enterprise.soap.sforce.com">
<types>
<schema elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:enterprise.soap.sforce.com">
<!-- Our simple ID Type -->
<simpleType name="ID">
<restriction base="xsd:string">
<length value="18"/>
<pattern value='[a-zA-Z0-9]{18}'/>
</restriction>
</simpleType>
</schema>
<schema elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:sobject.enterprise.soap.sforce.com">
<import namespace="urn:enterprise.soap.sforce.com" />
<!-- Base sObject (abstract) -->
<complexType name="sObject">
<sequence>
<element name="fieldsToNull" type="xsd:string" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
<element name="Id" type="ent:ID" nillable="true" />
</sequence>
</complexType>
<complexType name="AggregateResult">
<complexContent>
<extension base="ens:sObject">
<sequence>
<any namespace="##targetNamespace" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="Contact">
<complexContent>
<extension base="ens:sObject">
<sequence>
<element name="Email" nillable="true" minOccurs="0" type="xsd:string"/>
<element name="FirstName" nillable="true" minOccurs="0" type="xsd:string"/>
<element name="LastName" nillable="true" minOccurs="0" type="xsd:string"/>
</sequence>
</extension>
</complexContent>
</complexType>
</schema>
<schema elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://soap.sforce.com/2005/09/outbound">
<import namespace="urn:enterprise.soap.sforce.com" />
<import namespace="urn:sobject.enterprise.soap.sforce.com" />
<element name="notifications">
<complexType>
<sequence>
<element name="OrganizationId" type="ent:ID" />
<element name="ActionId" type="ent:ID" />
<element name="SessionId" type="xsd:string" nillable="true" />
<element name="EnterpriseUrl" type="xsd:string" />
<element name="PartnerUrl" type="xsd:string" />
<element name="Notification" maxOccurs="100" type="tns:ContactNotification" />
</sequence>
</complexType>
</element>
<complexType name="ContactNotification">
<sequence>
<element name="Id" type="ent:ID" />
<element name="sObject" type="ens:Contact" />
</sequence>
</complexType>
<element name="notificationsResponse">
<complexType>
<sequence>
<element name="Ack" type="xsd:boolean" />
</sequence>
</complexType>
</element>
</schema>
</types>
<!-- Method Messages -->
<message name="notificationsRequest">
<part element="tns:notifications" name="request"/>
</message>
<message name="notificationsResponse">
<part element="tns:notificationsResponse" name="response"/>
</message>
<!-- PortType -->
<portType name="NotificationPort">
<operation name="notifications">
<documentation>Process a number of notifications.</documentation>
<input message="tns:notificationsRequest"/>
<output message="tns:notificationsResponse"/>
</operation>
</portType>
<!-- Binding
You need to write a service that implements this binding to receive the notifications
-->
<binding name="NotificationBinding" type="tns:NotificationPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="notifications">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<!-- Service Endpoint -->
<service name="NotificationService">
<documentation>Notification Service Implementation</documentation>
<port binding="tns:NotificationBinding" name="Notification">
<soap:address location="http://www.myserver.com/salesforceoutboundprototype/notificationport.svc"/>
</port>
</service>
</definitions>
tldr is I need to implement NotificationBinding so that Salesforce can call my webservice when an event occurs on their system.
I since have realised svcutil does not natively support Contract-First development.
As per Contract-First SOA with WCF I used WSCF.Blue to generate server-side stubs from Salesforce wsdl. Whilst the code compiles wsdl generated by my service does not have the required notifications operation.
I wonder what I am going wrong?
So I managed to do quick implementation of Salesforce wsdl using wsdl.exe and /serverInterface and it seems the wsdl generated by asmx based application is quite different from wcf based application.
This is the interface created by wsdl.exe with /serverInterface
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")]
[System.Web.Services.WebServiceBindingAttribute(Name="NotificationBinding", Namespace="http://soap.sforce.com/2005/09/outbound")]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(sObject))]
public interface INotificationBinding {
/// <remarks/>
[System.Web.Services.WebMethodAttribute()]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlElementAttribute("notificationsResponse", Namespace="http://soap.sforce.com/2005/09/outbound")]
notificationsResponse notifications([System.Xml.Serialization.XmlElementAttribute("notifications", Namespace="http://soap.sforce.com/2005/09/outbound")] notifications notifications1);
}
This is the interface created by WSCF.Blue
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://soap.sforce.com/2005/09/outbound", ConfigurationName="INotificationPort")]
public interface INotificationPort
{
// CODEGEN: Generating message contract since the operation notifications is neither RPC nor document wrapped.
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(sObject))]
notificationsResponse1 notifications(notificationsRequest request);
}
They seem to be fairly similar so I don't know why wsdl generated by these application would be so different? Is it worthwhile adding wsdls (don't want to make the question any longer then it already is)?
You may not like what I suggest but I believe it will actually be the best option for you. Use ASMX. I have three OM listeners and they all work just fine under 4.0
I do not know who spreads these misfinfromations about some .NET2.0 techs but a lot of them are most certainly not obsoleted just because dev community got stricken with novelty fetish; ASMX is one of them (so is Linq2SQL, etc). WCF is simply put not yet complete, it is not fully WS compliant and that casues a lot of grief with salesforce integration (most painful being that WCF does not support soap headers where salesforce keeps session info).
For more info why asmx is NOT obsolete, see here: Does .net 4.0 still support asmx
Use svcutil to generate a client proxy and simply delete the client proxy implementation, and keep the service/data contracts. The service contract is symmetrical from a client/server point of view. I have worked on substantial contract-first projects and found this to be perfectly adequate.
Just make sure you have all of the external WSDLs available to for svcutil to resolve. I see several import statements in your WSDL text above.
BTW, WSCF.Blue is not quite up to it unfortunately as it's not been updated for a few months and is unlikely to be so in the future. Sadly, the primary developer died in a car crash last year (yes, really.)
I went through the same pain of trying to get my OBM listener working with WCF. I had originally only set up an OperationContract for the notifications method. After deploying I soon realised a Data Contract would need to be set up which I did but due to time constraints and not being entirely sure if that would be all I needed to do I simply switched to an asmx web service which worked.
I figured out an easy way to generate WCF interfaces from the Salesforce WSDL using the built in Visual Studio tools. I downloaded the WSDL from Salesforce and saved it to my desktop. In Visual Studio, go to the add service reference menu in one of your projects(doesn't matter where, you're going to delete this). For the Url, type in the path to the WSDL you downloaded locally (i.e. C:\Users\yourusername\Desktop\notification.wsdl)
This should bring load in the data for the service. Click okay to create the reference and now in the services references folder, double click on the reference you just created. This should show you the object browser with the namespace of the service reference you just created being highlighted. Double click on any of the classes inside this namespace and it will open up the related reference.cs that was generated by visual studio.
Copy all of the content inside the namespace declaration to the file of your choice with whatever namespace you decide. You can rename that interface as well if you plan to handle more than one outbound message (default should be NotificationPort). The interface will have references to the namespace you built it with but you can remove all of the namespacing in the file because all of the classes it is referring to are in the same file.
Create a new WCF service class. Delete the interface that is automatically created with the svc file and change the interface name to the one that you just copied to the new file.
By default, Visual Studio created some an async method which was throwing errors when I tried to implement it. I just deleted it from the interface and used the standard notification method.
I did this in VS2013 but it should be the same for 2010 and 2012 as well. Make sure you are using 'Add Service Reference' and not 'Add Web Reference'. Don't forget to delete the generated reference as you will not be using it.
WSCF provides a contract-first tool with VS integration.

Server did not recognize the value of HTTP Header SOAPAction initiate

i have a simple web method. when i call it i get the below error.
Server did not recognize the value of HTTP Header SOAPAction initiate.
we call the webmethod from java client and we add the below code to the header.
addRequestHeader("SOAPAction", "initiate");
how to add it to the header in the server code (C#)?
I've decided to post my own answer here because I've lost a few hours on this and I think that, although the accepted answer of this other question (http://stackoverflow.com/questions/352174/server-did-not-recognize-the-value-of-http-header-soapaction/14084341#14084341) is very good and pointed me in the right direction (yes, it got a voteup), it was not detailed enough to explain what was wrong with my application, at least in my case.
I'm running a BPEL module in OpenESB 2.2 and the Test Case of my Composite Application was failing with the following error:
Caused by: System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: .
After doing some research I've noticed that the external WSDL has all the clues we need to fix this problem, e.g., I'm using the following web service to validate a credit card number through a orchestration of Web Services: http://www.webservicex.net/CreditCard.asmx?WSDL
If you check the
<wsdl:binding name="CCCheckerSoap" type="tns:CCCheckerSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="ValidateCardNumber">
<soap:operation soapAction="http://www.webservicex.net/ValidateCardNumber" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
...
But, once you create the Composite Application and build the project with the BPEL that invokes this external WSDL service, for some reason (bug?), the XML of the Composite Application Service Assembly (CASA) binding is generated with an empty soapAction parameter:
<binding name="casaBinding1" type="ns:CCCheckerSoap">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="ValidateCardNumber">
<soap:operation soapAction="" style="document"/>
<input>
<soap:body use="literal"/>
</input>
Once you copy the proper soapAction (http://www.webservicex.net/ValidateCardNumber) into this parameter, the application's Test Case will correctly and return the expected Soap response.
<soap:operation soapAction="http://www.webservicex.net/ValidateCardNumber" style="document"/>
So, it's a more specific solution that I decided to document based on the information found in this blog post: http://bluebones.net/2003/07/server-did-not-recognize-http-header-soapaction/.
It means (at least in my case) that you are accessing a web service
with SOAP and passing a SOAPAction parameter in the HTTP request that
does not match what the service is expecting.

Categories

Resources