Answered by:
WCF MessageContract and SOAP Headers

Question
-
User-1753096817 posted
Hi,
I have gained an understanding of what MessageContracts are, but have found it difficult to progress and use that knowledge to my advantage.
My problem is as follows.
I have a SOAP request coming into my WCF service as follows:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:nu:services:schema:message:common:nuiesbmetadata:v01"
xmlns:urn1="urn:nu:services:schema:message:common:nuiesbcontext:v01"
xmlns="urn:uk:gi:dis:supplierengagement:v02">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wssu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"> weYI3nXd8LjMNVksCKFV8t3rgHh3Rw==
</wsse:Password>
<wsse:Nonce>WScqanjCEAC4mQoBE07sAQ==</wsse:Nonce>
<wssu:Created>2013-04-16T01:24:32Z</wssu:Created>
</wsse:UsernameToken>
</wsse:Security>
<urn:ESBMetaData>
<urn:OriginalServiceCallerID>SomethingIsNotWorking</urn:OriginalServiceCallerID>
</urn:ESBMetaData>
<urn1:ESBContext soapenv:mustUnderstand="1">
<urn1:BusinessContextType>SomethingIsNotWorking-DoSomething</urn1:BusinessContextType>
<urn1:BusinessContextInstanceId>uuid:7dc57353-9069-dd2d-8b69-163f676dd3e3</urn1:BusinessContextInstanceId>
<urn1:ServiceRequestId>uuid:7dc57353-9069-442d-8b69-163f676dd3e3</urn1:ServiceRequestId>
</urn1:ESBContext>
</soapenv:Header>
<soapenv:Body>
.......
.......
.......
</soapenv:Body>
</soap:Envelope>
So from the above I know I need to create some classes that use the MessageContract Attrribute, but what I cannot see from the examples shown how to populate the structure (ie If I have a method exposed on a WCF endpoint, how is the MessageContract populated with, either all of the above header, or just a section of it, say the wsse:UsernameToken section)?
This is the sort of examples that I have found so far:
http://www.codeproject.com/Articles/318810/WCF-Service-Method-Level-Security-using-Message-Co
But this implies that the only way to populate the message contract is to return it from the function call.
Thursday, September 26, 2013 5:31 AM
Answers
-
User-1753096817 posted
Moved onto WCF
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, December 3, 2013 7:22 AM
All replies
-
User1519735232 posted
Rather than define a DataContract, use MessageContract
[MessageContract] public class YourMessageType { // This is in the SOAP Header [MessageHeader] public string UserName {get;set;} [MessageHeader] public string Password {get;set;} // This is in the SOAP body [MessageBodyMember] public string OtherData {get;set;} ... }
Thursday, October 3, 2013 10:19 PM -
User-1753096817 posted
Thank you I will try it out.
My only concern was that I thought that that would work if you had the format of <soapheader><UserName> whereas mine is <soapheader><security><username>.
Anyway I will try and report back.
Monday, October 7, 2013 6:55 PM -
User-1753096817 posted
Have tried to find to use this solution, but everyone out there in internet land just seams to quote the same as the above, which is great, but does not help as it does not show the implementation of said MessageContract.
A simple working sample would be very beneficial.
So far I have created a class called MyMessage
Imports System.ServiceModel Imports System.Xml <MessageContract()> _ Public Class MyMessage Private _SOAPHeader As XElement Private _SOAPBody As XElement <MessageHeader()> _ Public Property SOAPHeader As XElement Get Return _SOAPHeader End Get Set(value As XElement) _SOAPHeader = value End Set End Property <MessageBodyMember()> _ Public Property SOAPMessgae As XElement Get Return _SOAPBody End Get Set(value As XElement) _SOAPBody = value End Set End Property End Class
And an interface file called IReadMySoap
Imports System.ServiceModel ' NOTE: You can use the "Rename" command on the context menu to change the interface name "IReadMySOAP" in both code and config file together. <ServiceContract()> Public Interface IReadMySOAP <OperationContract()> _ Sub DoWork(ByVal message As MyMessage) End Interface
' NOTE: You can use the "Rename" command on the context menu to change the class name "ReadMySOAP" in code, svc and config file together. Public Class ReadMySOAP Implements IReadMySOAP Public Sub DoWork(ByVal message As MyMessage) Implements IReadMySOAP.DoWork Try Dim a As String a = "Just stop here" Dim rtn = New MyMessage Dim srcTree As XElement = _ <Root> <Element1>1</Element1> <Element2>2</Element2> <Element3>3</Element3> <Element4>4</Element4> <Element5>5</Element5> </Root> Dim xmlTree As XElement = _ <Root> <NewElement>Content</NewElement> </Root> xmlTree.Add( _ From el In srcTree.Elements _ Where CInt(el) >= 3 _ Select el) rtn.SOAPMessgae.Add(xmlTree) Catch ex As Exception Dim rtn = New MyMessage Dim srcTree As XElement = _ <Root> <Element1>Errors have err'ed</Element1> </Root> Dim xmlTree As XElement = _ <Root> <NewElement>Content</NewElement> </Root> xmlTree.Add( _ From el In srcTree.Elements _ Where CInt(el) >= 3 _ Select el) rtn.SOAPMessgae.Add(xmlTree) End Try End Sub End Class
Am I going along the right lines?
Thursday, October 10, 2013 7:26 AM -
User-1753096817 posted
Moved onto WCF
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, December 3, 2013 7:22 AM