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!
Related
I am trying to get all parameters,methods etc of a wsdl service which there is no documentation.
The web page of the wsdl service is:
https://www1.gsis.gr/wsicisnet/MessageProcessorService?wsdl
I found that in
https://www1.gsis.gr/wsicisnet/MessageProcessorService?xsd=3
there are some attributes that are required
<xs:attribute name="traderID" type="xs:string" use="required"/>
<xs:attribute name="wsUserID" type="xs:string" use="required"/>
<xs:attribute name="wsPass" type="xs:string" use="required"/>
but when I try to send the message it gives me an error
RulesConditionasError: SubmittingTraderIdentification
([SubmittingTraderIdentification: null] must be the same as the
trader ID (801063350)
I can't find anywhere any attribute or parameter for SubmittingTraderIdentification .
Can someone help me out?
EDIT:
When I load the wsdl service in SoapUI and generate a request it look like this
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:icis="http://icis.externaldomain.services.ws">
<soapenv:Header/>
<soapenv:Body>
<icis:processIncomingMessageRequest>
<!--Optional:-->
<icis:messageRequest traderID="?" wsUserID="?" wsPass="?">
<DigitallySignedMessage messageType="?" isXmlString="?">
<xmlMessage>?</xmlMessage>
</DigitallySignedMessage>
</icis:messageRequest>
</icis:processIncomingMessageRequest>
</soapenv:Body>
</soapenv:Envelope>
EDIT 2:
This is the XML that I try send from my program:
<?xml version="1.0" encoding="utf-8"?>
<EF15A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Header>
<MessageSender>TRADER.GR</MessageSender>
<MessageRecipient>NES.EL</MessageRecipient>
<DateOfPreparation>2020-10-06</DateOfPreparation>
<TimeOfPreparation>16:30:00</TimeOfPreparation>
<MessageIdentifier>20/198</MessageIdentifier>
</Header>
<Body>
<DeclarationOfExciseTaxesRegistration>
<SubmittingOperator>
<SubmittingOperatorIdentification>1234567</SubmittingOperatorIdentification>
<SubmittingTraderIdentification>1234567</SubmittingTraderIdentification>
</SubmittingOperator>
<ExciseTaxesDeclaration>
<LocalReferenceNumber>1544237495/20/198</LocalReferenceNumber>
<Fallbackflag>0</Fallbackflag>
<RegistrationOffice>GR004531</RegistrationOffice>
<DocumentState>0</DocumentState>
<DocumentNumber>1</DocumentNumber>
<TotalDocuments>1</TotalDocuments>
<NumberOfRows>1</NumberOfRows>
<DispatchCountry>BG</DispatchCountry>
<DestinationCountry>GR</DestinationCountry>
<ExistenceOfContainerFlag>0</ExistenceOfContainerFlag>
<DeliveryConditions>FCA</DeliveryConditions>
<Currency>EUR</Currency>
<InvoiceAmount>6600.00</InvoiceAmount>
<ExchangeFactor>1</ExchangeFactor>
<ChemicalAnalysisPerformedFlag>0</ChemicalAnalysisPerformedFlag>
<ThroughSimplifiedProcedureFlag>0</ThroughSimplifiedProcedureFlag>
<PaymentMethodCode>H</PaymentMethodCode>
<CertificateIssuanceFlag>1</CertificateIssuanceFlag>
<DeclarationTypeCode>30</DeclarationTypeCode>
<CalculationOfTaxesDate>2020-10-06</CalculationOfTaxesDate>
<GeneralChemistryDetails />
<DeliveryDetails>
<TransportVehicleIdentificationNumber>K4423NBA</TransportVehicleIdentificationNumber>
<TransportVehicleCountry>BG</TransportVehicleCountry>
<NationalTransportMode>3</NationalTransportMode>
</DeliveryDetails>
<ClearingAgent>
<ClearingAgentType>1</ClearingAgentType>
<ClearingAgentEORI>GR1234567</ClearingAgentEORI>
</ClearingAgent>
</ExciseTaxesDeclaration>
<ExciseTaxesDeclarationConsignor>
<ExciseTaxesDeclarationConsignorType>0</ExciseTaxesDeclarationConsignorType>
</ExciseTaxesDeclarationConsignor>
<ExciseTaxesObligee>
<ObligeeType>7</ObligeeType>
<ObligeeIdentificationType>1</ObligeeIdentificationType>
<ObligeeIdentification>1234567</ObligeeIdentification>
<ContactDetails />
</ExciseTaxesObligee>
<ExciseTaxesDeclarationConsignee>
<ConsigneeType>0</ConsigneeType>
<ConsigneeIdentificationType>1</ConsigneeIdentificationType>
<ConsigneeIdentification>1234567</ConsigneeIdentification>
<ContactDetails />
<SpecialConsignee>
<SpecialConsigneeLicenseType>1</SpecialConsigneeLicenseType>
</SpecialConsignee>
<VesselRegistrationDetails>
<VesselRegistrationType>1</VesselRegistrationType>
</VesselRegistrationDetails>
</ExciseTaxesDeclarationConsignee>
<ExciseTaxesRow>
<ExciseTaxesDeclarationRowNumber>1</ExciseTaxesDeclarationRowNumber>
<SymbolNumbers>ΔΙΠΛΟΚΑΜΠΙΝΟ ΦΟΡΤΗΓΟ FORD RANGER ΚΥΛ:2500 ΕΤΟΥΣ:2007</SymbolNumbers>
<TaricCode>8704219900</TaricCode>
<TaricAdditionCode>1901</TaricAdditionCode>
<TaxQuantity>1</TaxQuantity>
<CountryOfOrigin>SE</CountryOfOrigin>
<GrossWeight>3020.000</GrossWeight>
<NetWeight>3020.000</NetWeight>
<ConditionIdentification>48</ConditionIdentification>
<PreviousConditionIdentification>00</PreviousConditionIdentification>
<ExemptionCode>P12</ExemptionCode>
<StatisticalValue>6600.00</StatisticalValue>
<SupplementaryComputationInformation>
<SupplementaryComputationInfo>816 </SupplementaryComputationInfo>
<SupplementaryComputationValue>6600.00</SupplementaryComputationValue>
</SupplementaryComputationInformation>
<PreviousDocuments>
<PreviousDocumentType>4</PreviousDocumentType>
<PreviousAsdeDocument />
<PreviousEaadDocument />
<PreviousStampRequestDocument />
<PreviousVehicleArrivalDocument>
<DeclarationReferenceNumber>19GRVA44531810</DeclarationReferenceNumber>
</PreviousVehicleArrivalDocument>
<PreviousVehicleMovementDocument />
<PreviousExciseTaxesDeclarationDocument />
</PreviousDocuments>
<ReferenceDocuments>
<ReferenceDocumentId>1E04</ReferenceDocumentId>
<ReferenceDocumentNumber>2048764105</ReferenceDocumentNumber>
</ReferenceDocuments>
<ReferenceDocuments>
<ReferenceDocumentId>1E05</ReferenceDocumentId>
<ReferenceDocumentNumber>1018744363</ReferenceDocumentNumber>
</ReferenceDocuments>
<ReferenceDocuments>
<ReferenceDocumentId>3</ReferenceDocumentId>
<ReferenceDocumentNumber>969/2019</ReferenceDocumentNumber>
</ReferenceDocuments>
<ReferenceDocuments>
<ReferenceDocumentId>4</ReferenceDocumentId>
<ReferenceDocumentNumber>2593/2018</ReferenceDocumentNumber>
</ReferenceDocuments>
<ReferenceDocuments>
<ReferenceDocumentId>1</ReferenceDocumentId>
<ReferenceDocumentNumber>14.03.2019</ReferenceDocumentNumber>
</ReferenceDocuments>
<VehicleDetails>
<FrameNumber>WF1053539371</FrameNumber>
<CarKind>8</CarKind>
<ImporterCodeOrBrandName>13</ImporterCodeOrBrandName>
<FirstAllowanceDate>2007-12-18</FirstAllowanceDate>
<VehicleFactoryType>2AW</VehicleFactoryType>
<VehicleUsedFlag>1</VehicleUsedFlag>
<EngineCapacity>2500</EngineCapacity>
<EngineType>WL</EngineType>
<FuelType>ΠΕΤΡΕΛΑΙΟ</FuelType>
<MakeYear>2007</MakeYear>
<VehicleModelName>RANGER</VehicleModelName>
<ImportedDate>2019-02-19</ImportedDate>
<CountryLast>SE</CountryLast>
<MileageType>456</MileageType>
<CarbonDioxideEmissionsType>456</CarbonDioxideEmissionsType>
<VehicleRebateFlag>0</VehicleRebateFlag>
</VehicleDetails>
<TaxComputation>
<NationalAccountingCode>504</NationalAccountingCode>
<SuspensionFlag>0</SuspensionFlag>
<AmountOfTaxes>686.4</AmountOfTaxes>
<PaymentMethodCode>H</PaymentMethodCode>
<TaxBase>6600.00</TaxBase>
<TaxRate>10,4000</TaxRate>
</TaxComputation>
<SpecialMentions />
</ExciseTaxesRow>
</DeclarationOfExciseTaxesRegistration>
</Body>
</EF15A>
We have the same problem with EF15 submission through web service.
SubmittingTraderIdentification is never passed even if it is completed inside the xml message.
Greek custom authorities have not an explanation for this problem.
Our customers manually upload ef15 xml file
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.
We have a WSDL which contains the following type definition:
...
<xsd:complexType name="OrderItem">
<xsd:all>
<xsd:element name="source" type="xsd:string" />
</xsd:all>
</xsd:complexType>
<xsd:complexType name="OrderItems">
<xsd:sequence>
<xsd:element name="item" type="tns:OrderItem" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
...
When adding the service as a Service Reference in VS 2010, the OrderItems class contains an item property which is of type OrderItem[]. The SOAP request is then generated as follows:
...
<items>
<OrderItem>
<item>foo</item>
<item>bar</item>
</OrderItem>
</items>
...
Using the XmlArray and XmlArrayItem attributes we can control the names of the <OrderItem> and <item> elements respectively, but can't get to the desired structure:
...
<items>
<item>foo</item>
<item>bar</item>
</items>
...
I'm aware that this problem could be avoided if the WSDL specified something like <xsd:restriction base="soap-enc:Array"> rather than an unbounded sequence, but given the above is the only way forward to use some custom serialization?
EDIT: Example WSDL at https://gist.github.com/1422704
It seems that .NET WCF services do not play nice with our WSDL (which was manually created with a focus on the XSD and not on SOAP).
The easiest way to get the SOAP API to work with .NET was to alter the WSDL to use the SOAP array type, so <items> becomes a soap-enc:Array with soap-enc:arrayType="tns:OrderItem[]".
The resulting XML generated by the Service Reference's auto-generated code is then correct.
I am on Magento 1.4.1.1 and I am trying to setup a custom function in the API using SOAP v2. I have it working for SOAP v1 but I need v2 so that C# can use it. For v2 the function shows up in the WSDL but alwasy returns this error: Procedure 'testFoo' not present.
Here are my files:
/app/etc/modules/ABT_Test.xml
<?xml version="1.0"?>
<config>
<modules>
<ABT_Test>
<active>true</active>
<codePool>local</codePool>
</ABT_Test>
</modules>
</config>
/app/code/local/ABT/Test/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<ABT_Test>
<active>true</active>
<codePool>local</codePool>
<version>1.0</version>
</ABT_Test>
</modules>
<global>
<models>
<test>
<class>ABT_Test_Model</class>
</test>
</models>
</global>
</config>
/app/code/local/ABT/Test/etc/api.xml
<?xml version="1.0"?>
<config>
<api>
<resources>
<test>
<model>test/api</model>
<title>ABT Test Api</title>
<methods>
<foo translate="title" module="test">
<title>Foo Test</title>
<method>foo</method>
<acl>test/foo</acl>
</foo>
</methods>
</test>
</resources>
<v2>
<resources_function_prefix>
<test>test</test>
</resources_function_prefix>
</v2>
</api>
</config>
/app/code/local/ABT/Test/etc/wsdl.xml
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
</schema>
</types>
<message name="testFooRequest">
<part name="sessionId" type="xsd:string" />
</message>
<message name="testFooResponse">
<part name="result" type="typens:boolean" />
</message>
<portType name="{{var wsdl.handler}}PortType">
<operation name="testFoo">
<documentation>Test Foo</documentation>
<input message="typens:testFooRequest" />
<output message="typens:testFooResponse" />
</operation>
</portType>
<binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="testFoo">
<soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
<input>
<soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
</binding>
</definitions>
/app/code/local/ABT/Test/Model/API.php
<?php
class ABT_Test_Model_Api extends Mage_Api_Model_Resource_Abstract
{
public function foo()
{
return true;
}
}
?>
/app/code/local/ABT/Test/Model/API/V2.php
<?php
class ABT_Test_Model_Api_V2 extends ABT_Test_Model_Api
{
}
?>
And here is the code I use to test the API:
<?php
$mageUser = '########';
$mageApiKey = '########';
//SOAP V1
echo "SOAP V1 <br />";
$mageUrl = 'http://www.########.com/api/soap/?wsdl';
$soap = new SoapClient($mageUrl, array('cache_wsdl' => 0));
try {
$sessionID = $soap->login($mageUser, $mageApiKey);
var_dump($soap->call($sessionID, 'test.foo', array()));
} catch (Exception $e) {
echo 'Exception: ' . $e->getMessage() . '<br />';
}
//SOAP V2
echo "SOAP V2 <br />";
$mageUrl2 = 'http://www.########.com/api/v2_soap/?wsdl';
$soap2 = new SoapClient($mageUrl2, array('cache_wsdl' => 0));
try {
$sessionID2 = $soap2->login($mageUser, $mageApiKey);
var_dump($soap2->testFoo($sessionID2));
} catch (Exception $e) {
echo 'Exception: ' . $e->getMessage() . '<br />';
}
?>
I obscured the username, password and url. The function shows up in the v2 WSDL and the php code recognizes that it is in the WSDL but I still get the error: Procedure 'testFoo' not present.
So what am I missing?
EDIT:
I did what Zyava suggested and it got my example working. I then copied the folder and did an exact (case sensitive) find and replace to use a meaningful Module name and function name. I was careful to pick names that I didn't think would be reserve words. On the new module the call on the v1 WSDL works fine but the v2 gives the same "Procedure 'xxx' not present" message. I then went and renamed the method on the test from 'Foo' to 'Fooz' and I got this message: "Resource path is not callable." I find it interesting that I get a different message. This leads me to believe there is some cache/configuration/something that is causing the problem. Any ideas?
At first I should warn you that Magento doesn't support SOAP v2 format for now, api/v2_soap/?wsdl is just second version of soap api.
1.
<models>
<test>
<class>ABT_Test_Model</class>
</test>
</models>
Because you are writing module which isn't core, you should write <abt_test>
2.<model>test/api</model>. Should be <model>abt_test/api</model> in your case.
3.<acl>test/foo</acl>.
Does this acl section exist in your adminhtml.xml?
bygrace,
your code is so perfect!
add
....
<resources_alias>
<test>test</test>
</resources_alias>
.....
same level with
<resources> and <v2>
on Api.xml
and it'll be working good.
I has having the same issue and i tried clearing the tmp file as i had hosted it using xampp it didnt work i was getting Procedure ххх not present exception, I had to disable the cache management in the admin page of the server.
How to disable Cache in Admin page
In the admin page under the system there is a section called cache management disable everything during the development phase or else any change you do wont be reflected in the wsdl.
QUICK SUMMARY:
Taleo has a single operation "Dispatcher WSDL" that is supposed to return a URL for use with its WebAPI WSDL ... the purpose is to allow the URL to be for all intents and purposes soft coded.
For operation getURL,
WcfTestClient.exe XML view shows that in the SOAP envelope a URL has been returned.
However, WcfTestClient.exe formatted view shows
Name: (return) Value: (null) Type: NullObject
My c# vs2010 .NET 4 code; taleoURL is always null
DispatcherAPIClient dispatcherClient = new DispatcherAPIClient("rpcrouter");
string taleoOrgCode = "TALEOSK";
string taleoURL = dispatcherClient.getURL(taleoOrgCode);
if (taleoURL == null) Console.WriteLine("null returned for " + taleoOrgCode);
This null is strange because here is the XML response from WcfTestClient.exe:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" />
<SOAP-ENV:Body>
<ns1:getURLResponse xmlns:ns1="urn:TBEDispatcherAPI" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:string">https://tbe.taleo.net/NA12/ats/services/rpcrouter</return>
</ns1:getURLResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
https://tbe.taleo.net/NA12/ats/services/rpcrouter is the value
of the <return> element.
To be able to use the above link, obviously I need taleoURL to be not null.
Pages 154-155 of the Taleo API guide say that
getURL's defined as string getURL(string orgCode)
http://tbe.taleo.net/products/TBE_API_Guide.pdf from
http://www.taleo.com/solutions/taleo-business-edition-web-integration-api
also
http://tbe.taleo.net/wsdl/DispatcherAPI.wsdl
http://tbe.taleo.net/wsdl/WebAPI.wsdl
Here's the Request/Response part of DispatcherAPI.wsdl:
<wsdl:message name="getURLRequest">
<wsdl:part name="orgCode" type="xsd:string" />
</wsdl:message>
<wsdl:message name="getURLResponse">
<wsdl:part name="getURLReturn" type="xsd:string" />
</wsdl:message>
My best guess is that I'm missing something.
This is a case where my own ignorance is not bliss.
MSDN and Google have not helped.
Thank you ... Gerry
I just started working with the Taleo WebAPI and I'm having the same issue.
Update: I changed the reference from a VS2010 C# Service Reference to an "old school" Web Reference and then it worked. I'm still working on a "real" solution, but that does work.