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)?
IHttpHandler
and practice your XML parsing skills :) Seriously, this approach is the most flexible as each Outbound Message has a unique WSDL. – Jackfruit