Handling custom soap header in WCF Service - c#

I am creating WCF Service to receive a message (strings). It has soap request has header as shown below. I went thru so many example that I found on internet, but I could not understand any of those thoroughly.
I found this article is very helpful but still could not make it works
http://weblogs.asp.net/paolopia/handling-custom-soap-headers-via-wcf-behaviors
After reading several article, I come to know that I need to handle the following area (a)SOAP Header (b) Message Inspector (c) Client Context and (d) Server Context class
How do I handle mustUnderstand header
I need to capture value passed messageid, ReplyTo, To, From, Action
The following soap message need to be consumed
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header>
<a:Action s:mustUnderstand="1">urn:ihe:iti:2007:ProvideAndRegisterDocumentSet-b</a:Action>
<a:From><a:Address>urn:oid:1.2.3.4.5.6.1234567.10.70.142.2</a:Address>
</a:From>
<a:MessageID>urn:uuid:3a40ebfe-2abc-4de9-b6f6-06c7962f6050</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To>https://localhost/MyWCFService/Service.asmx</a:To>
</soapenv:Header>
...

If you are creating a WCF Service and you try inspect the SOAP message, you can implement the IDispatchMessageInspector Interface Also, for WCF client refer to IClientMessageInspector Interface
These are some usefull links:
http://ianpicknell.blogspot.com.tr/2011/03/implementing-idispatchmessageinspector.html
How to use IDispatchMessageInspector in a WCF Service?

Related

OcppV1.5 over Soap Error: Action does not exist

i am currently building a Client to communicate with a Gateway of a Charge Point.
The communication is build with OcppV1.5 over Soap & Http.
The Server doesn't accept my request. I get a Http Response 500 with the Error Reason:
"XML Request is not well formed, Action does not exist."
I looked into the wsdl files but I just don't understand why it doesn't accept my action.
My Request looks something like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="https://www.w3.org/2005/08/addressing" xmlns:cs="urn://Ocpp/Cp/2012/06/">
<SOAP-ENV:Header>
<cs:chargeBoxIdentity>0000.0000</cs:chargeBoxIdentity>
<wsa:From>
<wsa:Address>http://000.000.000.000:0000</wsa:Address>
</wsa:From>
<wsa:To>http://000.000.000.001:0001</wsa:To>
<wsa:Action>/ChangeConfiguration</wsa:Action>
<wsa:MessageID>00000.000000000000</wsa:MessageID>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<cs:changeConfigurationRequest>
<cs:key>MeterValueSampleInterval</cs:key>
<cs:value>60</cs:value>
</cs:changeConfigurationRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Update:
As Bogdan suggested I tried to send the same message using SoapUi and it worked. The generated Request from SoapUi looks like this:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ns="urn://Ocpp/Cp/2012/06/">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<ns:chargeBoxIdentity>000000.00000</ns:chargeBoxIdentity>
<wsa:Action>/ChangeConfiguration</wsa:Action>
<wsa:ReplyTo>
<wsa:Address>http://000.000.000.000:0000</wsa:Address>
</wsa:ReplyTo>
<wsa:MessageID>uuid:00000000-0000-0000-0000-000000000000</wsa:MessageID>
<wsa:To>http://000.000.000.000:00000/</wsa:To>
</soap:Header>
<soap:Body>
<ns:changeConfigurationRequest>
<ns:key>MeterValueSampleInterval</ns:key>
<ns:value>300</ns:value>
</ns:changeConfigurationRequest>
</soap:Body>
</soap:Envelope>
It's hard to tell from what you posted why you are getting an error, so I can only add some information that can hopefully allow you to troubleshoot the issue.
Your message has WS-Addressing headers, <wsa:Action> being one of them. The value of this field should be specified in the WSDL if your WSDL also includes WS-Addressing Metadata information, or should be specified in the documentation of the web service you are invoking. Your error message "XML Request is not well formed, Action does not exist" seems to indicate that there might be an issue with this field, but there is another action that SOAP services have which is a SOAP action. I asked about it in the comment above to make sure it's eliminated as a source of problems. In SOAP 1.1 it's called SOAPAction and is a separate HTTP header, while in SOAP 1.2 it's an action parameter on the HTTP Content-Type header. Based on the http://www.w3.org/2003/05/soap-envelope namespace, you have a SOAP 1.2 message.
With these explanations layed out, I suggest you take the WSDL and feed it to SoapUI who can generate sample requests that you can use to invoke the web service. If the WSDL also contains WS-Addressing Metadata, SoapUI should be able to pick it up and help you fill in the values you need. If not, look again through the WSDL for Action elements (make sure you differentiate between the SOAP Action and the WS-Addressing Action using their XML namespaces) or through the service documentation.
Once you get a succesfull call using SoapUI, then try to duplicate it with your code. At that point you can again use SoapUI to troubleshoot things and inspect your code built message to see it resembles the one you can successfully send with SoapUI.
Hope this helps get you closer to a resolution.

Generating SOAP Action Header on Wcf-Custom Send Port

I am in the process of creating a Send Port in Biztalk, that uses the Wcf-Custom adapter for sending SOAP requests.
So far I have been testing the SOAP requests in Visual Studio, using C# code from the System-ServiceModel namespace. See code below:
/ CODEGEN: Generating message contract since the operation transferPayments is neither RPC nor document wrapped.
[System.ServiceModel.OperationContractAttribute(Action="urn:CorporateService:transferPayment", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute()]
transferPaymentsResponse transferPayments(transferPayment1 request);
[System.ServiceModel.OperationContractAttribute(Action="urn:CorporateService:transferPayment", ReplyAction="*")]
System.Threading.Tasks.Task<transferPaymentsResponse> transferPaymentsAsync(transferPayment1 request);
I need to add this "transferPayment" action to the SOAP Action Header field in the adapter.
Using the provided example, I've come up with this
<BtsActionMapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Operation Name="TransferPayment" Action="http://bankconnect.dk/schema/2014/CorporateService/TransferPayment" />
</BtsActionMapping>
Where "http://bankconnect.dk/schema/2014" is the namespace, "CorporateService" is the service, and "TransferPayment" is the action. I'm unsure if this is the correct way to go about implementing this.
My question how I should format the SOAP Action Headers, so that they correspond to the c# code used.
I'd suggest you use the BizTalk WCF Service Consume Wizard to generate the schema's inside BizTalk. This would make all the possible Actions for you.

How to consume SOAP Siebel webservices in .net

Hi I am developing web application which contains Siebel web service integration. All request/response cycle will take place through XML. It is basically SOAP service. I do not have idea on siebel and soap xml. I am trying to integrate siebel service in WebAPi2. Client have provided me request and response and created sample service to test. I am able to invoke siebel service in fidler. In my webapi2 i want to integrate service.
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rol="Some Url">
<soapenv:Header/>
<soapenv:Body>
<rol:process>
<rol:IDType>National Id</rol:IDType>
<rol:Type>Customer</rol:Type>
// other parametrs
</rol:process>
</soapenv:Body>
</soapenv:Envelope>
Below is the response
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header>
<wsa:MessageID>urn:some id</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:FaultTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
</wsa:FaultTo>
</env:Header>
<env:Body>
<processResponse xmlns="some url">
<result>1-198A3H</result>
<Contact_Integration_Id>1-198A3H</Contact_Integration_Id>
<SIEBEL_ERROR_CODE/>
<SIEBEL_ERRROR_MESSAGE/>
</processResponse>
</env:Body>
</env:Envelope>)
Also they have provided Public url to hit the API.
As i do not know Siebel integration in .Net and i did not find any suitable tutorial I am expecting some help from here. Any help/suggestion i get here highly appreciated. Thank you.
Although #AJPerez is correct that this is not really a Siebel issue, I would like to recommend you request for the WSDL (Web Service Definition file) from which your example message is generated. Without it you'll find it hard to use the generic .NET tutorials regarding web services.
.NET has no doubt a generator that takes a WSDL as input and generates a set of classes and functions for you to use.

Calling soap with C# script in a SSIS Script Task

Well that's a mouthful for a title. Let me start out by saying that I am not a programming per se but a DBA. I can write some MSSQL query with the best of them but my knowledge of C# is pretty limited. I have a piece of software that I need to communicate with via web services to push some data to all within the constraints of SQL Server Integration Services. I can read from the DB directly but I can not write to it. I'm querying some data, emailing that data, and I need to write back to the software for reach record we emailed through web services. The WSDL is available but like I said, zero knowledge of C#. I was able to build a SOAP envelope through SOAPUI that works perfectly and I would like to figure out a way call SOAP using a C# script in my SSIS package.
I have also tried to run this in the Web Service Task in SSIS and my WSDL file only gives me 4 methods when I should have close to a hundred. It would be easier there to sort out but I understand there are some limitations with the SSIS Web Service Task.
I have seen this thread: Client to send SOAP request and received response
Which unfortunately does not work for me when I copy and paste my SOAP and header into the code. To throw another wrench this thing, this is a protected web services which requires 3 credentials to have a token issued for passing data back and forth. A side question is can I run multiple SOAP calls (first to authenticate, then to push my data into the web service) through a C# script?
Here was my second soap call after getting the token that I was able to run:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"xmlns:v2="http://www.WSAPI.AMS360.com/v2.0">
<soapenv:Header>
<v2:WSAPIAuthToken>
<v2:Token>tokenremoved</v2:Token>
</v2:WSAPIAuthToken>
</soapenv:Header>
<soapenv:Body>
<v2:InsertActivity_Request>
<!--Optional:-->
<v2:Activity>
<v2:AssignedTo>93725c05-f77b-49a1-9edd-6ce9fd5505c1</v2:AssignedTo>
<!--Optional:-->
<v2:ActivityType>customer</v2:ActivityType>
<v2:ActivityAction>% of ownership</v2:ActivityAction>
<!--Optional:-->
<v2:ActivityDate>11/04/2014</v2:ActivityDate>
<!--Optional:-->
<v2:ActivityTime>11:54</v2:ActivityTime>
<!--Optional:-->
<v2:EmployeeCode>!$5</v2:EmployeeCode>
<v2:Description>web services test code successfully inserted</v2:Description>
</v2:Activity>
</v2:InsertActivity_Request>
</soapenv:Body>
</soapenv:Envelope>

WCF messageheader vs messagebodymember?

I do not understand when I should put the [MessageHeader] instead of the [MessageBodyMember]?
I have read that it's used to conform some protocol like Soap, but still, what does it change at the end?
SOAP is a protocol in which each message (request or response) is made up of two parts: the Header and the Body, inside an Envelope:
<s:Envelope xmlns:s='the namespace for the soap version'>
<s:Header>
<!-- SOAP headers will come here -->
</s:Header>
<s:Body>
<!-- SOAP body members will come here -->
</s:Body>
</s:Envelope>
You normally wouldn't use [MessageContract] (and MessageHeader or MessageBodyMember) in WCF services, only if you really need to interop with some 3rd party which expects the data in a certain format.
I think when I want to put something independent of message content, I will put it in the message header.
And if you want another party to read something from your message, it should be put in the header, because sometimes you may allow someone to read the message header not message body as it contains confidential contents.
You can think about it as difference between message data (MessageBodyMember) and message metadata (MessageHeader). There is plenty of build in standardized headers provided by WCF which deals with addressing, security, reliable messaging, etc. In default WCF implementation it is related only to SOAP.
There is also general rule that in complex messaging architecture there can be intermediaries who read metadata and use them to some processing and message routing (they can even add additional metadata) but they should never interfere with message body (data). In case of security they can even not be able to read message body or some metadata (headers).
In case of WCF you are able to set different security requirements (none, signed, signed and encrypted) for each message header and for whole message body (WCF doesn't support separate security requirements for different body parts). That can also lead to some decision about using body member or header.
For example if you decide to make some custom authentication, or transferring some client information in each message you will probably create custom header for that but real data payload related to the operation will be part of message body.

Categories