Reputation: 27
I wrote c# code for a Soap XML request, I have verified this code generating an XML class.
My question is how to send request and receive response using c# code.
Please be kind with my simple or basic mistakes because I am a newbie to XML but your help would be really appreciated.
SOAP XML Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ce="http://www." xmlns:os="http://www.domainname.com/schema/soap/v1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<soapenv:Header />
<soapenv:Body>
<ce:message>
<ce:m_control>
<os:control_timestamp>2001-12-31T12:00:00</os:control_timestamp>
<os:message_id>000000000000000000000000000000000</os:message_id>
<os:message_type>Contract Enquiry Request</os:message_type>
<os:message_version>ce/v2.2/NameContractRequest</os:message_version>
<os:expected_response_type>synchronous</os:expected_response_type>
<os:initiator_id>initiator_id</os:initiator_id>
<os:initiator_orchestration_id>initiator_orchestration_id</os:initiator_orchestration_id>
<os:KeyInfo>
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>CN=OSIS Customer CA, O=Origo Secure Internet Services Ltd., CN=OSIS Customer CA</ds:X509IssuerName>
<ds:X509SerialNumber>111111111111111111111111111111111111</ds:X509SerialNumber>
</ds:X509IssuerSerial>
<ds:X509SubjectName>C=GB, O=FirmID3400010000023NR11QQ, OU=CPS - www.unipass.co.uk/cps, OU=Warning/Terms of Use - www.unipass.co.uk/tou, OU=EmployeeID10101101010101, OU=TPSP2, OU=BPNR1 1QQ, CN=Testt Orgg/[email protected]</ds:X509SubjectName>
</ds:X509Data>
</os:KeyInfo>
<os:responder_id>os:responder_id</os:responder_id>
</ce:m_control>
<ce:m_content>
<ce:b_control>
<ce:contract_enquiry_reference>TestRequest</ce:contract_enquiry_reference>
</ce:b_control>
<ce:intermediary>
<ce:FirmFSARef id="idvalue14">456123</ce:FirmFSARef>
</ce:intermediary>
<ce:request_scope>
<ce:contract_details_required_ind>No</ce:contract_details_required_ind>
<ce:valuation_currency>GBP</ce:valuation_currency>
<ce:fund_code_type_required>SEDOL</ce:fund_code_type_required>
<ce:valuation_request ce:type="Current" />
</ce:request_scope>
<ce:contract>
<ce:contract_reference_number>TL12345678</ce:contract_reference_number>
</ce:contract>
</ce:m_content>
</ce:message>
</soapenv:Body>
</soapenv:Envelope>
################################################ c# code ##################
Guid CEGuid = Guid.NewGuid(); string GuidString = CEGuid.ToString();
string CEVersion = "";
string URL = "";
string ResponderId = "";
string ContractDetailsRequired = "Yes";
using (XmlTextWriter xmlRequestWriter = new XmlTextWriter(@"C:/Unipass/PensionRequest.xml", Encoding.UTF8))
{
xmlRequestWriter.WriteStartDocument();
xmlRequestWriter.WriteComment("This file is generated by the program.");
xmlRequestWriter.WriteStartElement("soapenv:Envelope");
xmlRequestWriter.WriteAttributeString("xmlns:soapenv", null, "http://schemas.xmlsoap.org/soap/envelope/");
xmlRequestWriter.WriteAttributeString("xmlns:ce", null, "http://www.WhateveryDomain.com/schema/ce/v2.2/WhateverRequest");
xmlRequestWriter.WriteAttributeString("xmlns:os", null, "http://www.WhateveryDomain.com/schema/soap/v1");
xmlRequestWriter.WriteAttributeString("xmlns:ds", null, "http://www.w3.org/2000/09/xmldsig#");
xmlRequestWriter.WriteStartElement("soapenv:Header");
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteStartElement("ce:message");
xmlRequestWriter.WriteStartElement("ce:m_control");
xmlRequestWriter.WriteElementString("os:control_timestamp", DateTime.Now.ToString("s"));
xmlRequestWriter.WriteElementString("os:message_id", GuidString);
xmlRequestWriter.WriteElementString("os:message_type", "Contract Enquiry Request");
xmlRequestWriter.WriteElementString("os:message_version", "ce/v2.2/WhateverRequest");
xmlRequestWriter.WriteElementString("os:expected_response_type", "synchronous");
xmlRequestWriter.WriteElementString("os:initiator_id", "initiator_id");
xmlRequestWriter.WriteElementString("os:initiator_orchestration_id", "initiator_orchestration_id");
xmlRequestWriter.WriteStartElement("os:KeyInfo");
xmlRequestWriter.WriteStartElement("ds:X509Data");
xmlRequestWriter.WriteStartElement("ds:X509IssuerSerial");
xmlRequestWriter.WriteElementString("ds:X509IssuerName", "CN=OSIS Customer CA, O=Origo Secure Internet Services Ltd., CN=OSIS Customer CA");
xmlRequestWriter.WriteElementString("ds:X509SerialNumber", "111111111111111111111111111111111");
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteElementString("ds:X509SubjectName", "C=GB, O=FirmID3400010000023NR11QQ, OU=CPS - www.unipass.co.uk/cps, OU=Warning/Terms of Use - www.unipass.co.uk/tou, OU=EmployeeID01200012000003, OU=TPSP2, OU=BPNR1 1QQ, CN=Testt Orgg/[email protected]");
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteElementString("os:responder_id", "os:responder_id");
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteStartElement("ce:m_content");
xmlRequestWriter.WriteStartElement("ce:b_control");
xmlRequestWriter.WriteElementString("ce:contract_enquiry_reference", "TestRequest");
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteStartElement("ce:intermediary");
xmlRequestWriter.WriteStartElement("ce:FirmFSARef");
xmlRequestWriter.WriteElementString("id", "456123");//="idvalue14">
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteStartElement("ce:request_scope");
xmlRequestWriter.WriteElementString("ce:contract_details_required_ind", "Yes");
xmlRequestWriter.WriteElementString("ce:valuation_currency", "GBP");
xmlRequestWriter.WriteElementString("ce:fund_code_type_required", "SEDOL");
xmlRequestWriter.WriteStartElement("ce:valuation_request");
xmlRequestWriter.WriteElementString("ce:type", "Current");//"ce:type","Current"
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteStartElement("ce:contract");
xmlRequestWriter.WriteElementString("ce:contract_reference_number", "PP12345678");
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteEndDocument();
xmlRequestWriter.Flush();
Please could you tell me how to send Request and receive response from WCF service using above code.
Even though I have added wsdl reference but I don't know how to pass XmlElement[] in the line below.
serviceReference.getDetail(ref XmlElement[] Any);
Here is a method in Reference class.
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://www.domainname.com/whatever/webname/schema/ce/v2.2/NameContractServic" +
"e", ConfigurationName="TestingPension.NameContractServiceDetailType")]
public interface NameContractServiceDetailType {
// CODEGEN: Generating message contract since the wrapper namespace (http://www.domainname.com/schema/ce/v2.2/NameContractRequest) of message getDetailRequest does not match the default value (http://www.domainname.com/name/name/schema/ce/v2.2/NameContractService)
[System.ServiceModel.OperationContractAttribute(Action="http://www.origostandards.com/schema/ce/v2.2/CEPensionSingleContract#getDetail", ReplyAction="*")]
[System.ServiceModel.FaultContractAttribute(typeof(SoapReqResWebApplication.TestingPension.Error[]), Action="http://www.domainname.com/schema/ce/v2.2/NameContract#getDetail", Name="errors", Namespace="http://www.domainname.com/schema/tech/v1.0/SOAPFaultDetail")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
SoapReqResWebApplication.TestingPension.getDetailResponse getDetail(SoapReqResWebApplication.TestingPension.getDetailRequest request);
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="message", WrapperNamespace="http://www.domainname.com/schema/ce/v2.2/NameContractRequest", IsWrapped=true)]
public partial class getDetailRequest {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="", Order=0)]
[System.Xml.Serialization.XmlAnyElementAttribute()]
public System.Xml.XmlElement[] Any;
public getDetailRequest() {
}
public getDetailRequest(System.Xml.XmlElement[] Any) {
this.Any = Any;
}
}
@CodeCaster
I tried your code as:
var documentToSend = new XmlDocument();
//// TODO: add all elements you like
using (XmlTextWriter xmlRequestWriter = new XmlTextWriter(@"C:/Unipass/Request.xml", Encoding.UTF8))
{
xmlRequestWriter.WriteStartDocument();
xmlRequestWriter.WriteStartElement("ce:message");
xmlRequestWriter.WriteEndElement();
xmlRequestWriter.WriteEndDocument();
xmlRequestWriter.Flush();
documentToSend.Save(xmlRequestWriter);
//// Create an array with the root message node as only element.
var xmlToSend = new XmlElement[] { documentToSend.DocumentElement }; //xmlToSend = null
}
Might be I am doing completely wrong, please can you tell me why xmlToSend is null.
Upvotes: 1
Views: 2964
Reputation: 151594
It seems like WCF's proxy generator cannot create a class from the provided WSDL/XSD, given the generated method signature is getDetailRequest(System.Xml.XmlElement[] Any)
. What does a tool like SoapUI say about the WSDL?
A way to solve this is to indeed manually generate the message, which is just the <ce:message>..</ce:message>
block. WCF will wrap it in a proper SOAP envelope when you call the service method.
You'll have to play around a bit with the XmlDocument
class, but I think something like this will do it:
// Create an XmlDocument and fill it
var documentToSend = new XmlDocument();
// TODO: add all elements you like
// Create an array with the root message node as only element.
var xmlToSend = new XmlElement[] { documentToSend.DocumentElement };
// Call the service.
var response = serviceReference.getDetail(xmlToSend);
Another way would be to manually recreate the request class in C# and populate and serialize an instance of it to XML when sending a request. The ultimate way would be to fix the XML so Add Service Reference (SvcUtil) can generate classes from the service's metadata.
As for your edit, you're not writing the XML elements to the documentToSend
, but you write them to your file.
Upvotes: 0
Reputation: 8880
It seems that you are writing code by hand to serialise messages into SOAP/XML. The SOAP request example is an actual instance document rather than WSDL, yes? This is one of the things that WCF does for you - you should not need to generate your own SOAP messages.
In WCF, you focus on the object types you want to transmit and the operations you want to support. Then WCF does all the heavy lifting of SOAP serialisation for you. That is the main point of WCF really.
It's quite hard to decipher from your sample SOAP message what exactly you are trying to do, so I would recommend looking at one of the simple WCF samples, say from here
http://msdn.microsoft.com/en-us/library/vstudio/ms751514(v=vs.90).aspx
Get a simple one up and running using wsHttpBinding or basicHttpBinding (these are SOAP bindings in WCF). Then capture the HTTP request using Fiddler or similar and see what WCF has done for you in terms of the SOAP envelope generation.
You should then be able to translate that to your own case.
Upvotes: 1