Salesforce Outbound Messaging的Contract-First WCF

mob*_*kie 17 c# wcf salesforce

我正在寻找为Salesforce Outbound Messaging实现监听器应用程序.

穿行使用过时的ASMX Web服务它实现.使用wsdl.exe和/ serverInterface开关生成代码.

这是Salesforce Outbound Messaging的wsdl.

<?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>
Run Code Online (Sandbox Code Playgroud)

tldr是我需要实现NotificationBinding,以便Salesforce可以在系统上发生事件时调用我的webservice.

我已经意识到svcutil本身不支持Contract-First开发.

根据Contract-First SOA with WCF,我使用WSCF.Blue从Salesforce wsdl生成服务器端存根.虽然代码编译由我的服务生成的wsdl没有所需的通知操作.

我想知道我错了什么?


所以我设法使用wsdl.exe和/ serverInterface快速实现Salesforce wsdl,似乎基于asmx的应用程序生成的wsdl与基于wcf的应用程序完全不同.

这是wsdl.exe使用/ 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);
}
Run Code Online (Sandbox Code Playgroud)

这是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);
}
Run Code Online (Sandbox Code Playgroud)

它们似乎非常相似,所以我不知道为什么这些应用程序生成的wsdl会如此不同?是否值得添加wsdls(不想再问这个问题了)?

mmi*_*mix 5

您可能不喜欢我的建议,但我相信它实际上是您的最佳选择.使用ASMX.我有三个OM听众,他们都在4.0下工作得很好

我不知道是谁传播了这些关于某些.NET2.0技术的错误解释,但是很多这些技术肯定都没有被淘汰,因为开发社区遭受了新奇的迷恋; ASMX就是其中之一(Linq2SQL也是如此).WCF简单地说还没有完成,它不完全符合WS,并且在salesforce集成方面带来了很多麻烦(最痛苦的是WCF不支持salesforce保存会话信息的soap标头).

有关为什么asmx不会过时的详细信息,请参阅此处:.net 4.0是否仍支持asmx