none
Deserialize incoming soap message RRS feed

  • Question

  • Hey Folks,

    I'm sure this is answered somewhere, but it's just not clear to me.  Maybe there are too many answers and I'm not sure which one fits my situation.  I just need a direction, though any actual code would be nice.

    I have a WCF 4.5 web service in C#.  I need to consume an incoming SOAP message.  I know exactly what the message looks like.  It contains a header with the username and password, and a body containing the Payload amongst other parameters.  There seem to be 3 techniques and I'd like to know which to use.

    First, can my operation contract just have an input string and will that SOAP message be captured in the string?

    [OperationContract]
    string ReceiveSoap(string inputSoap);

      If so, I can just open an XML Document using that string and read the nodes.  The code would look like:

    xmlDoc.LoadXml(inputSoap);
    XmlNodeList xmlNodeHead = xmlDoc.GetElementsByTagName("wsse:UsernameToken");
    string userName = xmlNodeHead[0].ChildNodes[0].InnerText;
    string password = xmlNodeHead[0].ChildNodes[1].InnerText;
    XmlNodeList xmlNodeBody = xmlDoc.GetElementsByTagName("ns1:COREEnvelopeRealTimeRequest");
    string payLoad = xmlNodeBody[0].LastChild.InnerText;

    Or, option 2 seems to be to use the Message class to read the SOAP message and parse it.  The code I've seen out there for this seems really obscure.

    Or, option 3 would be to deserialize the message manually before it reaches the operation contract using something like:

    public interface IDispatchMessageFormatter
    {
      void DeserializeRequest(Message message, object[] parameters);
      Messagfe SerializeReply(MessageVersion messageVersion, object[] parameters, object result);
    }

    It's not clear to me whether option 2 is the same as option 3, or whether option 2 is a more current version of option 3.

    I've contacted the client and asked them to send me the actual request so I'll know exactly what I'm dealing with.  It's supposed to look like:

    <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
    	<soapenv:Header> 
    		<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true"> 
    			<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-21621663"> 
    				<wsse:Username>TMGTest</wsse:Username> 
    				<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">tmgtest</wsse:Password> 
    			</wsse:UsernameToken> 
    		</wsse:Security> 
    	</soapenv:Header>
    	<soapenv:Body>
    		<ns1:COREEnvelopeRealTimeRequest xmlns:ns1="http://www.caqh.org/SOAP/WSDL/CORERule2.2.0.xsd"> 
    			<PayloadType> X12_270_Request_005010X279A1</PayloadType> 
    			<ProcessingMode>RealTime</ProcessingMode> 
    			<PayloadID>f81d4fae-7dec-11d0-a765-00a0c91e6bf6</PayloadID> 
    			<TimeStamp>2007-08-30T10:20:34Z</TimeStamp> 
    			<SenderID>HospitalA</SenderID> 
    			<ReceiverID>PayerB</ReceiverID> 
    			<CORERuleVersion>2.2.0</CORERuleVersion> 
    			<Payload>
    				<![CDATA[ISA*00*          *00*          *ZZ*EDIFECSTEST    *ZZ*TMG HEALTH     *131017*0907*^*00501*000000000*0*P*:~GS*HS*EDIFECSTEST*TMG HEALTH*20131017*0907*0*X*005010X279A1~ST*270*0001*005010X279A1~BHT*0022*13**20131017*090710~HL*1**20*1~NM1*PR*2*NYSDOH*****FI*141797357~HL*2*1*21*1~NM1*1P*2*Affinity Health Plan*****SV*02802899~N3*2500 Halsey St.~N4*Bronx*NY*104613613~HL*3*2*22*0~NM1*IL*1*SMITH*THOMAS*C***MI*Y349853ND~N3*201 SOUTH ST*APT 201~N4*NOWHERE*PA*18701~DMG*D8*19451010*M~DTP*291*D8*20131017~EQ*30~HL*4*2*22*0~NM1*IL*1*JONES*SAMUEL*R***MI*Z888745TT~N3*RR#4 OUTSKIRT ROAD*BOX 876~N4*SOMEWHERE*PA*18222~DMG*D8*19380312*M~DTP*291*D8*20131017~EQ*30~SE*23*0001~GE*1*0~IEA*1*000000000~]]>
    			</Payload> 
    		</ns1:COREEnvelopeRealTimeRequest>
    	/soapenv:Body> 
    </soapenv:Envelope>

    Any direction on this much appreciated!


    • Edited by LWakeman Friday, November 29, 2013 3:23 PM
    Friday, November 29, 2013 3:12 PM

All replies

  • Hi,

    Since you already have the SOAP envelope, please try to check the below to deserialize incoming soap message:

    Message.CreateMessage(XmlReader enveloperReader, int maxSizeOfHeaders, MessageVersion version);

    And the code would look something like:

    string requestMessageString = @"<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
    <soapenv:Header> 
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true"> 
    <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-21621663"> 
    <wsse:Username>TMGTest</wsse:Username> 
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">tmgtest</wsse:Password> 
    </wsse:UsernameToken> 
    </wsse:Security> 
    </soapenv:Header>
    <soapenv:Body>
    <ns1:COREEnvelopeRealTimeRequest xmlns:ns1="http://www.caqh.org/SOAP/WSDL/CORERule2.2.0.xsd"> 
    <PayloadType> X12_270_Request_005010X279A1</PayloadType> 
    <ProcessingMode>RealTime</ProcessingMode> 
    <PayloadID>f81d4fae-7dec-11d0-a765-00a0c91e6bf6</PayloadID> 
    <TimeStamp>2007-08-30T10:20:34Z</TimeStamp> 
    <SenderID>HospitalA</SenderID> 
    <ReceiverID>PayerB</ReceiverID> 
    <CORERuleVersion>2.2.0</CORERuleVersion> 
    <Payload>
    	<![CDATA[ISA*00*          *00*          *ZZ*EDIFECSTEST    *ZZ*TMG HEALTH     *131017*0907*^*00501*000000000*0*P*:~GS*HS*EDIFECSTEST*TMG HEALTH*20131017*0907*0*X*005010X279A1~ST*270*0001*005010X279A1~BHT*0022*13**20131017*090710~HL*1**20*1~NM1*PR*2*NYSDOH*****FI*141797357~HL*2*1*21*1~NM1*1P*2*Affinity Health Plan*****SV*02802899~N3*2500 Halsey St.~N4*Bronx*NY*104613613~HL*3*2*22*0~NM1*IL*1*SMITH*THOMAS*C***MI*Y349853ND~N3*201 SOUTH ST*APT 201~N4*NOWHERE*PA*18701~DMG*D8*19451010*M~DTP*291*D8*20131017~EQ*30~HL*4*2*22*0~NM1*IL*1*JONES*SAMUEL*R***MI*Z888745TT~N3*RR#4 OUTSKIRT ROAD*BOX 876~N4*SOMEWHERE*PA*18222~DMG*D8*19380312*M~DTP*291*D8*20131017~EQ*30~SE*23*0001~GE*1*0~IEA*1*000000000~]]>
    </Payload> 
    </ns1:COREEnvelopeRealTimeRequest>
    	/soapenv:Body> 
    </soapenv:Envelope>";
    
    XmlReader envelopeReader = XmlReader.Create(new StringReader(requestMessageString));
    Message requestMsg = Message.CreateMessage(envelopeReader, int.MaxValue, MessageVersion.Soap11);
    

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, December 3, 2013 8:03 AM
    Moderator
  • Hi Amy, and thanks for the reply!

    However, I don't see how it helps.  Obviously, I'm not going to hard-code the XML and pass that in, so I'm still reading in a string (inputSoap) and using some technique - in my case XmlDocument, in your case XmlReader - to read the nodes.  I couldn't get your XmlReader to work though, I think because you have to move past the first element into the XML itself.  I couldn't figure out a way to do that, that works, using your XmlReader method - I presume XmlReader.Read().

    So, it looks like the consumer of the service just has to pass in a SOAP'ish string to the operation as stated at the top and use whatever technique that works to parse out the fields.  I thought there was something that deserialized the incoming SOAP message before it reached the operation so there would be no need of an inputSoap string.  Either that, or maybe something does deserialize it so I would need to have a parameterized list for the operation.

    Still wondering...

    Tuesday, December 3, 2013 8:53 PM